2012년 11월 8일 목요일

dojo.xhr*을 사용하여 Ajax에 권한 위임

dojo.xhr*을 사용하여 Ajax에 권한 위임

Ajax를 사용하는 웹 애플리케이션 작성은 일반적으로 XmlHttpRequest(XHR) 오브젝트를 작성하여 수행되며, 이 오브젝트는 주어진 URL로 HTTP 요청을 하여 요청 헤더와 본문을 전달하고, 응답이 성공적인 응답 본문이나 HTTP 실패 응답으로 리턴될 때 수행되어야 하는 조치를 정의하는 콜백 함수를 정의한다. 크로스 브라우저 XHR을 구현하는 과정은 아무래도 힘들 수밖에 없지만, 다행히도 Dojo를 이용하여 GET, POST, PUT  DELETE 요청을 가능하게 하는 일련의 dojo.xhr* 함수를 사용하면 이러한 힘든 작업을 상당히 완화할 수 있다.
제공되는 네 가지 함수는 다음과 같다.
  • xhrGet
  • xhrPost
  • xhrPut
  • xhrDelete
이러한 함수는 모두 동일한 구문을 따르며, 단일 특성 구성 오브젝트를 인수로 받는다. 이 오브젝트에서 작성하고자 하는 Ajax 요청의 다양한 특성을 정의할 수 있다. 또한, 이러한 옵션은 모든 XHR 함수에서 동일하다.
XHR 함수에서 사용 가능한 더 유용한 구성 옵션 중 일부는 다음과 같다.
url
이 옵션은 HTTP 요청이 작성되어야 하는 URL이다. 이 URL은 요청을 작성 중인 페이지와 같은 도메인과 포트의 조합으로 되어 있어야 한다.
handleAs
응답 처리 유형을 정의할 수 있게 한다. 기본값은 text이지만, json, javascript, xml 및 기타 두 가지 옵션이 사용 가능하다. 나중에 이 섹션에서는 JSON 응답 형식을 처리하는 콜백 함수를 사용하여 Ajax 요청을 작성하는 예제를 살펴볼 것이다.
form
<form> 요소의 문자열 ID 표현이나 참조이다. 양식에 있는 각 필드의 값은 요청과 함께 요청 본문으로서 전송된다.
content
요청 본문에 있는 자원에 전달할 매개변수를 포함하고 있는 오브젝트이다. 이 오브젝트는 form 특성에서 가져온 값과 혼합된다(이 두 값이 모두 제공되는 경우).
XHR 함수 예제는 목록 22에 표시되어 있다.

목록 22. XHR 함수 호출 예제
dojo.xhrGet({
    url: "save_data.php",
    content: {
        id: "100",
        first_name: "Joe",
        last_name: "Lennon"
    }
});


이 예제에서는 문서 자체와 같은 위치에 있는 save_data.php 파일에 비동기적으로 HTTP GET 요청을 한다. 또한, 컨텐츠 오브젝트의 특성을 매개변수로서 PHP 스크립트에 전달한다. PHP에서는 $_GET 변수를 사용하여 이러한 값을 검색한 후, 이 값을 데이터베이스에 저장한다.
이전 예제에서는 dojo.xhrGet을 사용하여 Ajax 요청을 호출하는 방법을 배웠다. 이 예제는 실제로 요청을 작성하기에 충분하지만, 이 예제에는 처리 및 응답 기능이 없다. 또한, 콜백 함수가 구성 오브젝트로 전달된다. 사용 가능한 옵션은 다음과 같다.
load
이 함수는 Ajax 요청이 성공적인 응답 메시지를 리턴할 때 실행된다. 응답 데이터와 요청 오브젝트는 매개변수로 이 함수에 전달된다.
error
이 함수는 Ajax 요청에 문제가 발생할 때 실행된다. 이러한 현상은 Ajax 요청에 지정되어 있는 URL이 올바르지 않은 경우, 요청 제한시간이 초과한 경우 또는 기타 HTTP 오류가 생기는 경우에 발생한다. 오류 메시지와 요청 오브젝트는 인수로서 전달된다.
handle
이 함수를 이용하면 로드 및 오류 콜백 함수를 하나의 함수로 결합할 수 있으며, 요청이 성공하든지 오류가 발생하든지 사실상 신경 쓰지 않는 경우에는 이렇게 하는 것이 유용하다.
다음 예제에서는 JSON 파일에서 데이터를 일부 로드하여 해당 페이지에 표시하는 로드 콜백 함수가 있는 Ajax 호출을 작성한다.
더 현실적인 예제를 작성하여 dojo.xhr* 함수를 충분히 테스트해보자. 우선 파일을 새로 작성한 후, 이 파일을 listing1.html과 같은 디렉토리에 삽입한 다음 이 파일에 JSON 데이터를 일부 추가한다. 이 파일의 컨텐츠는 목록 23에 표시되어 있다.

목록 23. data.json — Ajax 요청으로 처리할 JSON 데이터
{
    count: 4,
    people: [
        {
            first_name: "Joe",
            last_name: "Lennon",
            age: 25  
        },{
            first_name: "Darragh",
            last_name: "Duffy",
            age: 33
        },{
            first_name: "Jonathan",
            last_name: "Reardon",
            age: 30
        },{
            first_name: "Finian",
            last_name: "O'Connor",
            age: 23
        }
    ]
}


이제 Firebug에서 Ajax 요청을 작성하고, Dojo가 로드되도록 Firefox에서 listing1.html 페이지가 로드되었는지 확인한다. 이 요청은load 콜백 함수를 사용하여 JSON 응답을 처리하고 테이블을 페이지에 표시한다(목록 24 참조).

목록 24. Ajax를 사용하여 JSON 데이터를 로드하고 처리
dojo.xhrGet({
    url: "data.json",
    handleAs: "json",
    load: function(data) {
        var table = "<table border=\"1\">";
        table += "<tr><th>Name</th><th>Age</th>
</tr>";
        dojo.forEach(data.people, function(person) {
            table += "<tr><td>";
            table += person.first_name+" "+person.last_name;
            table += "</td><td>";
            table += person.age;
            table += "</td></tr>";
        });
        table += "</table>";
        dojo.place(table, dojo.body());
    }
});


Firebug에서 목록 24에 있는 코드를 시도한다. JSON 파일에서 로드한 데이터와 함께 테이블이 페이지에 동적으로 추가된다. 이 과정은 그림 5에 표시되어 있다.
chrome browser에서는 firefox에서처럼 data.json 처럼 파일로 받는건 안된다..

그림 5. Ajax로 JSON 데이터를 로드한 테이블
사람 이름 네 개와 해당 나이가 표시되어 있는 테이블이 있는 페이지 
실제로는 PHP, Python, ASP, .NET 또는 Java와 같은 서버측 언어를 사용하여, Ajax 요청을 통해 전달되는 매개변수를 기반으로 JSON 데이터를 동적으로 생성한다.
 

2012년 11월 2일 금요일

Dojo의 이벤트 처리

대부분의 Javascript 라이브러리에는 기본 Javascript 이벤트 처리의 크로스 브라우저 구현이 있어서 DOM 이벤트가 트리거될 때 호출될 함수를 연결할 수 있다. 이는 유용하지만 Dojo에서는 한층 더 진보된 개념을 취하여 함수를 다른 함수와 연결할 수 있게 하며, 이러한 것으로는 DOM 이벤트, 오브젝트 이벤트, 사용자 정의 함수 또는 "주제(이 섹션에서 나중에 논의함)"가 있다.
DOM 이벤트에 함수를 연결하는 첫 번째 방법은 dojo.connect 함수를 사용하는 것이다. 이점을 확인할 수 있는 가장 좋은 방법은 예제를 사용하는 것이다. Firebug 콘솔에서 목록 13에 있는 코드를 입력한다.

목록 13. dojo.connect를 사용하여 함수를 DOM 이벤트에 연결
var message = dojo.byId("message");
dojo.connect(message, "onclick", function() {
    alert(message.innerHTML);
});


이렇게 하면 목록 14와 같은 결과가 콘솔에 표시된다.

목록 14. 결과
>>> var message = dojo.byId("message"); dojo.connect..., function() 
                                              { alert(message.innerHTML); });
[div#message, "onclick", function(), 1]


결과는 우수하지만, 실제로 무엇인가를 수행할 만한 함수는 전혀 아니다. Dojo는 ID가 "message"인 요소의 click 이벤트 핸들러에 함수를 연결했다. 시험해 보려면 "This is a DIV element with id attribute message" 컨텐츠가 있는 화면에서 해당 메시지를 클릭한다. 그림 4와 같은 Javascript 경보 상자가 표시된다.

그림 4. DOM 이벤트에 함수 연결
A message box containing 'This is a DIV element with id attribute                     message.' 
멋지지 않은가? 배열에 있는 모든 항목에 이벤트를 연결하려면 어떻게 해야 할까? 예를 들어, 해당 페이지에서 순서없는 목록의 각 항목을 클릭하면 이 항목이 굵은체로 강조되도록 하려고 한다고 하자. 목록 15에 있는 코드를 사용하면 이 작업을 손쉽게 수행할 수 있다.

목록 15. 요소의 배열에 이벤트 연결
dojo.query("#list li").forEach(function(item) {
    dojo.connect(item, "onclick", function() {
        dojo.style(item, {
            fontWeight: "bold"
        });
    });
});


시험해 보면 제대로 작동할 것이다. Dojo를 이용하면 훨씬 더 간결한 방법으로 코드를 작성할 수 있다. forEach를 사용하여 배열을 반복하는 대신, 목록 16과 같이 NodeList.connect 바로 가기 함수를 사용하여 이 작업을 수행할 수 있다.

목록 16. 요소로 구성된 배열에 이벤트 연결(개선됨)
dojo.query("#list li").onclick(function(e) {
    dojo.style(e.target, {
        fontWeight: "bold"
    });
});


이미 목록에 이벤트를 연결했으므로 목록 16에 있는 코드를 시도하여 작동하는지 확인하기 전에 페이지를 다시 고친다. e 인수는Event 오브젝트에 대한 참조이며 이 오브젝트의 target 특성을 이용하여 이벤트가 개시된 요소를 식별할 수 있다. 이 특성을 사용하여 굵은체로 스타일이 지정되어야 하는 요소를 식별한다. 목록의 세 가지 항목을 클릭해 보면, 클릭한 후에는 각 항목이 굵은체로 바뀐다.
이전 예제에서는 함수를 DOM 이벤트에 연결했다. Dojo에서는 이와 같은 방법으로 함수를 다른 함수에 연결할 수 있다. 이러한 예는 물레 이미지를 페이지의 어딘가에 표시하는 함수가 될 수 있다. 사용자가 Ajax 함수를 수행할 때, 이 이미지가 표시되게 하려고 한다. 마찬가지로 이 함수가 응답을 리턴하면 이 이미지를 숨기고 싶다. dojo.connect를 사용하지 않으면 코드는 목록 17과 같은 형태가 된다.

목록 17. dojo.connect를 사용하지 않고 함수를 다른 함수에 연결하기
function toggleImage() {
    //Code to show/hide loading image goes here
}

function callAjax() {
    toggleImage();
    //Code to call Ajax function goes here
}

function handleResponse() {
    //Code to handle Ajax response goes here
    toggleImage();
}


이 코드에는 아무런 문제가 없지만, callAjax handleResponse 함수에서 toggleImage 함수가 수정되었다. 또 다른 함수 호출을 추가할 경우에는 이러한 함수를 수정하여 추가 호출이 포함되도록 해야 한다. 함수 자체에 함수 호출을 추가하는 대신에dojo.connect를 사용하여 이러한 함수를 서로 연결할 수도 있다. 목록 18에는 dojo.connect 메소드를 사용하는 방법이 표시되어 있다.

목록 18. dojo.connect를 사용하여 함수를 다른 함수에 연결
function toggleImage() {
    //Code to show/hide loading image goes here
}

function callAjax() {
    //Code to call Ajax function goes here
}

function handleResponse() {
    //Code to handle Ajax response goes here
}

dojo.connect(callAjax, toggleImage);
dojo.connect(handleResponse, toggleImage);


이러한 코딩 스타일이 모든 개발자에게 적합한 것은 아니지만, 이렇게 하면 코드를 훨씬 더 읽기 쉽게 하는 방식으로 코드를 체계화할 수 있다.
언급할 만한 가치가 있는 Dojo 이벤트 처리의 궁극적 특성은 주제에 발행하고 등록하는 기능에 있다. 이 기능은 Dojo 컴포넌트가 서로의 존재를 인식하고 있지 않은 경우에도 서로 상호 작용할 수 있게 한다. 예를 들어, 개인의 성명이 있는 message 오브젝트가 예상되는printName이라고 하는 주제를 정의하고 있었다고 하자. 그러면 이 주제에 등록하고, 또 다른 컴포넌트가 개인의 이름으로 이 주제에 발행할 때마다 콘솔에 이름을 표시하는 컴포넌트가 있을 수 있다. 목록 19에는 이러한 등록을 하는 예제가 표시되어 있다. (Firebug에서 이 예제를 자유롭게 사용해 보자.)

목록 19. 등록
dojo.subscribe("printName", function(msg) {
    console.log("The person's name is: "+msg.first_name+" "+msg.last_name);
});


이 주제에 발행하려면 해당 주제의 API에 연결된 오브젝트의 배열을 전달해야 한다. (이 경우에는 오브젝트에 성과 이름이 포함되어 있어야 한다.) 목록 20에 예제가 표시되어 있다.

목록 20. 주제에 발행하기
dojo.publish("printName", [
    {
        first_name: "Joe",
        last_name: "Lennon"
    }
]);


이 코드의 결과는 목록 21과 같다.

목록 21. 결과
>>> dojo.publish("printName", [ { first_name: "Joe", last_name: "Lennon" } ]);
The person's name is: Joe Lennon


아는 바와 같이 이 오브젝트를 printName 주제에 발행하면, 등록 함수가 해당 메시지를 콘솔에 출력한다.
출처: http://www.ibm.com/developerworks/kr/library/wa-ground/

dojo 기본 사항


Dojo에는 dojo.require 함수를 통해 파일에 있는 애플리케이션 클래스를 구조화하고 로드하는 패키지 시스템이 있다. 이 함수는 기본 dojo.js에서 아직 제공하지 않는 Dojo 툴킷의 일부를 로드할 수 있다.

DOM 유틸리티 함수

dojo.byId
dojo.byId 함수를 이용하면 id 속성을 사용하여 DOM 노드를 선택할 수 있다

dojo.query
한 번에 요소를 여러 개 참조할 경우에는 어떻게 해야 할까? 이러한 경우에 필요한 함수가 바로 dojo.query 함수이다.

페이지에 있는 순서없는 목록을 선택하는 경우에는 dojo.forEach 함수를 사용하지 않았다. 다음 섹션인 "배열 및 NodeLists"에서는 이 함수가 필요하지 않은 이유를 살펴보게 된다.


기타 유용한 유틸리티 함수

dojo.body 함수는 문서에 해당하는 dojo.body <body> 요소에 대한 참조와 문서 오브젝트 자체를 리턴한다. dojo.create를 이용하면 새 요소를 작성하고 그 속성을 정의하여 DOM에 배치하는 작업을 신속하게 처리할 수 있다.

dojo.place가 있으며 이 함수를 이용하면 기존 요소나 새 요소를 문서의 어느 위치에나 배치할 수 있다.dojo.empty는 예상하는 바와 같이 DOM 요소의 컨텐츠를 비운다. dojo.destroy는 노드 자체와 노드에 부속된 모든 하위 요소를 제거한다. 

배열 및 NodeList

NodeList
배열은 표준 Javascript에서 사용할 수 있으며 배열을 이용하면 값으로 구성된 콜렉션을 저장할 수 있다. Dojo의 확장된 배열. 여러 가지 헬퍼 함수를 포함한다.  모든 표준 배열 함수와 Dojo에 특정된 함수를 사용할 수 있다. 이전 섹션에서 설명한 dojo.query 함수를 사용하는 경우에는 리턴 값이 NodeList(즉, dojo.NodeList) 오브젝트가 된다.




살펴볼 만한 가치가 있는 첫 번째 함수는 이 기사의 이전 섹션에 있는 dojo.query 예제에서 이미 살펴본 dojo.forEach 함수이다. 이 함수를 이용하면 NodeList에 대한 반복자를 정의하여 NodeList의 각 항목에 적용될 함수를 제공할 수 있다
dojo.indexOf 함수를 이용하면 배열에서 특정 값이 있는 위치를 찾을 수 있다. 이점을 확인할 수 있는 가장 좋은 방법은 예제를 사용하는 것이다. 이전 섹션에서 작성한 목록 배열을 사용하여 값 name이 있는 배열의 인덱스를 확인해 보도록 하자(예:dojo.indexOf(list, "name");).
indexOf 의 결과 값은 0부터 시작함. 없는 경우는 -1로 리턴
 
dojo.filter 함수를 이용하면 또 다른 배열의 필터링된 버전인 새로운 배열을 작성할 수 있다.
var filteredList = dojo.filter(list, function(item) {
    return item != "is";
});

dojo.forEach(filteredList, "console.log(item)");

This results in the following output:

>>> var filteredList = dojo.filter(list, 
function(it...dojo.forEach(filteredList, "console.log(item)");
My
name
Joe


기타 NodeList 함수

 dojo.map 함수를 이용하면 기존 배열의 수정된 버전인 새 배열을 작성할 수 있다. 예를 들면, 금전상의 가치를 나타내는 숫자로 이루어진 배열이 있을 수 있다. 맵 함수를 사용하여 이러한 값으로 구성된 배열을 통화 형식으로 리턴할 수 있다.

dojo.some 함수를 이용하면 배열에 있는 하나 이상의 항목이 지정된 기준과 일치하는지 확인할 수 있다. 
dojo.every 함수는 배열에 있는 모든 항목이 지정된 기준과 일치하는지 확인하기 위해 사용된다






출처: http://www.ibm.com/developerworks/kr/library/wa-ground/








크롬 에서 번역 옵션 뜨는 거 막는 방법

버그 같은게 아니고 저 옵션의 기본 값이 제공으로 바뀐듯... 번역 옵션 제공을 비활성화하면 안 뜸. Chrome에서 웹페이지 번역 모르는 언어로 작성된 페이지를 방문할 때 다음 단계에 따라 Chrome이 페이지를 번역하도록 할 수 있습...