문제

Jeff Atwood를 복용 조언, 저는 제가 작성하고 있는 매우 기본적인 할 일 목록 애플리케이션에 JavaScript 라이브러리를 사용하기로 결정했습니다.내가 골랐어 Dojo 툴킷, 버전 1.1.1.처음에는 모든 것이 괜찮았습니다.제가 작성한 드래그 앤 드롭 코드는 처음에는 제대로 작동했습니다. 화면에서 작업을 드래그하여 우선 순위를 변경할 수 있으며, 각 드래그 앤 드롭 작업은 서버에 AJAX 호출을 보내는 이벤트 핸들러를 호출하여 이를 허용합니다. 순서가 변경된 것으로 알고 있습니다.

그런 다음 이메일 추적 기능을 추가했습니다.표준 사항:새로 수신되는 이메일에는 제목 줄에 고유 ID 번호가 첨부되어 있으며, 해당 문제에 대한 모든 후속 이메일은 회신할 때 제목에 해당 ID 번호를 남겨두기만 하면 추적할 수 있습니다.따라서 우리는 각각 고유한 ID 번호가 있는 미결 작업 목록을 갖고 있으며, 각 작업에는 시간순으로 정렬된 관련 이메일 목록이 있습니다.사용자가 작업 목록을 볼 때 해당 이메일의 텍스트를 사용할 수 있기를 원했기 때문에 각 작업 상자를 Dijit "트리" 컨트롤로 만들었습니다. 최상위 수준에는 작업 설명이 포함되고 분기에는 이메일 날짜가 포함됩니다. 각 분기의 단일 "리프"에는 이메일 텍스트가 포함됩니다.

첫 번째 문제:기본적으로 트리 보기가 완전히 접혀 있기를 원했습니다.Google을 상당히 광범위하게 검색한 후 여러 가지 솔루션을 찾았는데, 모두 이전 버전의 Dojo에는 유효한 것처럼 보였지만 내가 사용했던 솔루션에는 적용되지 않았습니다.나는 결국 가장 좋은 해결책은 단순히 각 분기/리프를 축소하는 Tree 컨트롤이 로드되었을 때 호출되는 이벤트 핸들러를 갖는 것인 것 같다는 것을 알아냈습니다.불행하게도 Tree 컨트롤이 인스턴스화되고 "시작" 이벤트 핸들러가 호출되었음에도 불구하고 가지와 잎은 여전히 ​​로드되지 않았습니다(데이터는 여전히 AJAX 호출을 통해 로드되고 있었습니다).그래서 모든 이메일 텍스트와 트리 구조가 서버 측에 추가되도록 시스템을 수정했습니다.이는 시작 이벤트 핸들러가 호출될 때 완전히 채워진 전체 Tree 컨트롤을 사용할 수 있음을 의미합니다.

따라서 시작 이벤트 핸들러는 트리를 완전히 축소합니다.다음으로, 나는 이메일 잎에 대한 좋은 형식의 텍스트를 갖는 "적절한" 방법을 찾을 수 없었습니다.이메일 텍스트를 리프에 넣을 수는 있지만 모든 HTML은 이스케이프되어 웹 페이지에 표시됩니다.Dojo의 문서(1.0 이전 버전의 코드와 예제가 포함되어 오래된 경향이 있음)와 Google에 대해 더 자세히 알아보세요.나는 결국 JavaScript가 각 리프 노드 내부에 있는 SPAN 요소를 읽고 innerHTML에서 이스케이프된 HTML 코드를 이스케이프 해제하도록 하는 솔루션을 생각해냈습니다.나는 Tree 컨트롤의 시작 이벤트 처리기에서 완전히 축소된 트리 코드를 사용하여 이 작업을 수행하는 코드를 넣을 것이라고 생각했습니다.

하지만...SPAN 요소는 사용자가 확장(노드를 확장하기 위해 클릭하는 트리 보기의 작은 "+" 기호)을 클릭할 때까지 실제로 생성되지 않는 것으로 나타났습니다.좋아요, 공평합니다. onExpand() 이벤트 핸들러나 그 이름이 무엇이든 다시 형식 지정 코드를 추가하겠습니다.존재하지 않는 것 같습니다.문서를 검색하고 Google을 검색했습니다.나는 Dojo의 "게시/구독" 이벤트 처리 시스템을 잘못 이해하고 있을 가능성이 높습니다. 하지만 주로 이에 대한 포괄적인 문서가 어디에도 없는 것 같기 때문에 그렇게 생각합니다. 에게?).

그래서 결국 제가 생각해 낼 수 있는 최선의 해결책은 onClick 이벤트 핸들러("Dojo" 이벤트가 아니라 Dojo가 전혀 모르는 일반 JavaScript 이벤트)를 각 트리 분기의 확장 노드에 추가하는 것입니다. -각 리프의 SPAN 요소 내부에 HTML 형식을 지정합니다.제외하고...호출되면 SPAN 요소가 여전히 존재하지 않습니다(때때로 더 혼란스럽게 하기 위해 캐시된 경우도 있음).따라서 이벤트 처리기에 관련 SPAN 요소가 아직 표시되었는지 확인하고 다시 포맷하기 전에 확인하는 함수를 주기적으로 호출하는 타이머를 설정했습니다.

// An event handler called whenever a "email title" tree node is expanded.
function formatTreeNode(nodeID) {
    if (dijit.byId(nodeID).getChildren().length != 0) {
        clearInterval(nodeUpdateIntervalID);
        messageBody = dijit.byId(nodeID).getChildren()[0].labelNode.innerHTML
        if (messageBody.indexOf("<b>Message text:</b>") == -1) {
            messageBody = messageBody.replace(/&gt;/g, ">");
            messageBody = messageBody.replace(/&lt;/g, "<");
            messageBody = messageBody.replace(/&amp;/g, "&");
            dijit.byId(nodeID).getChildren()[0].labelNode.innerHTML = "<b>Message text:</b><div style=\"font-family:courier\">"+messageBody+"</div>";
        }
    }
}

// An event handler called when a tree node has been set up - we changed the default fully-expanded to fully-collapsed.
function setupTree(theTree) {
    dijit.byId("tree-"+theTree).rootNode.collapse();

    messageNode = dijit.byId("tree-"+theTree).rootNode.getChildren();
    for (pl = 0; pl < messageNode.length; pl++) {
        messageNode[pl].collapse();
        messageNode[pl].expandoNode.onclick = eval("nodeUpdateIntervalID = setInterval(\"formatTreeNode('"+messageNode[pl].id+"')\",200); formatTreeNode('"+messageNode[pl].id+"');");
    }
}

위의 내용은 정말 끔찍한 해킹처럼 느껴지며, 내 사고 과정 초기에 어딘가에서 잘못된 방향으로 전환했음이 틀림없다고 생각합니다.누군가 나에게 말해 줄 수 있습니까?

  • Dojo/Dijit Tree 컨트롤 내에 보기 좋게 형식화된 텍스트를 넣는 올바른 방법입니다.
  • 내가 구독할 수 있는 이벤트가 무엇인지 확인할 수 있는 Dojo 이벤트를 처리하는 올바른 방법입니다.
  • 사용하기 더 좋은 JavaScript 라이브러리(JQuery로 원하는 것을 수행하고 위에서 본 만능 접근 방식을 피할 수 있습니까?)

추신:소프트웨어 프로젝트의 이름을 지정하는 경우 Google에서 해당 이름의 고유성을 고려하세요. 모든 무술 결과를 방해하지 않고 Google에서 "Dojo" 문서를 검색하는 것이 더 쉬울 것이라고 확신합니다.

조달청:Firefox 맞춤법 검사기는 "Atwood" 철자를 아는 방법으로 'T'를 하나 대신 두 개 넣으면 수정해 줍니다.제프가 이제 그렇게 유명해졌나요?

도움이 되었습니까?

해결책

나는 당신이 따라했다고 가정합니다 Dojo 1.1의 dijit.Tree 및 dojo.data 데이터 저장소를 사용하여 트리 컨트롤에 데이터를 전달하도록 지시한 튜토리얼입니다.그 때문에 한동안 벽돌 벽에 머리를 부딪히게 되었습니다.

실제로는 훌륭한 접근 방식이 아니며 대안이 실제로 잘 문서화되어 있지 않습니다.대신 사용 모델을 만들어야 합니다.아래에는 LDAP 디렉터리의 구조를 표시하기 위해 만든 트리 모델의 예가 포함되어 있습니다.

./dijit/_tree/model.js의 Dojo 배포판에서 모델의 기본 구현을 찾을 수 있습니다.설명은 모델에서 지원하는 기능을 이해하는 데 도움이 됩니다.

아래 코드의 IDirectoryService 클래스는 다음에서 생성된 서버측 Java POJO용 스텁입니다. 직접 웹 원격 (DWR).클라이언트-서버 상호 작용을 많이 하려는 경우 DWR을 적극 권장합니다.

dojo.declare("LDAPDirectoryTreeModel", [ dijit.tree.model ], {
    getRoot : function(onItem) {
        IDirectoryService.getRoots( function(roots) {
            onItem(roots[0])
        });
    },

    mayHaveChildren : function(item) {
        return true;
    },

    getChildren : function(parentItem, onComplete) {
        IDirectoryService.getChildrenImpl(parentItem, onComplete);
    },

    getIdentity : function(item) {
        return item.dn;
    },

    getLabel : function(item) {
        return item.rdn;
    }
});

그리고 여기에 모델을 생성하고 이를 사용하여 트리 컨트롤을 채우는 내 JSP 페이지에서 발췌한 내용이 있습니다.

<div
  dojoType="LDAPDirectoryTreeModel"
  jsid="treeModel"
  id="treeModel">
</div>
<div
  jsid="tree"
  id="tree"
  dojoType="dijit.Tree" model="treeModel"
  labelAttr="name"
  label="${directory.host}:${directory.port}">
</div>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top