2012-09-22 27 views
0

我正在嘗試做一個簡單的任務。此任務是將一個包含dijit.Form的HTML加載到ContentPane中。在加載此HTML之前,我不知道需要哪個dijits,但加載的HTML將包含適用的require的加載它們。如何在解析的dojo中使用dijit需要ContentPane

因此,爲了能夠從加載的HTML執行腳本,我使用了dojox.layout.ContentPane。但是,當我將parseOnLoad設置爲true時,解析發生在之前的腳本執行,因此dijits在第一次加載內容時不可用。另外,當我嘗試使用onDownloadEnd回調時,當此回調運行時,來自require的dijits仍未加載。

我唯一能想到的就是使用setTimeout將解析推遲到執行這些腳本的時候。但我不喜歡這種解決方案,因爲它可能會不時失敗,並且會使應用程序的責任減少。

那麼我應該如何執行解析,以便它在加載的HTML中的require語句運行後立即生效?

回答

2

樣本見http://jsfiddle.net/zA9cJ/1/我可以看到兩個可能的解決方案 - 無論是與dijit/layout/ContentPane

  1. 使用Dojo 1.8.0,作爲解析器支持auto require,它會加載依賴關係本身,你可以看到這裏:http://jsfiddle.net/phusick/vr4h4/

  2. 把依賴列表在您的表單模板的某處插入,例如在data-config屬性您dijit/form/Form的:

    <form 
        data-dojo-type="dijit.form.Form" 
        data-config='"deps":["dijit/form/Form", "dijit/form/TextBox", "dijit/form/Button"]'> 
    
        <input data-dojo-type="dijit.form.TextBox" data-dojo-props="placeholder:'TextBox'"> 
        <button data-dojo-type="dijit.form.Button">Button</button> 
    
    </form> 
    

    設置parseOnLoad:falsedijit/layout/ContentPane,加載模板,得到的依賴關係的列表,require他們,然後在工廠函數parser.parse()containerNodeContentPane(看到它在行動http://jsfiddle.net/phusick/QA4gH/) :

    require([ 
        "dojo/ready", 
        "dojo/dom", 
        "dojo/query", 
        "dojo/on", 
        "dojo/parser", 
        "dojo/json", 
        "dijit/layout/ContentPane", 
        "dojo/domReady!" 
    ], function(ready, dom, query, on, parser, JSON) { 
    
        var template, dijits; 
    
        ready(function() { 
         template = dom.byId("template").textContent; 
         on.once(dom.byId("loadFormButton"), "click", loadForm); 
         contentPane1.set("parseOnLoad", false); 
         contentPane1.on("load", parseForm); 
        }); 
    
        function loadForm() { 
         contentPane1.set("content", template); 
        } 
    
        function parseForm() { 
         // a node to parse 
         var node = contentPane1.containerNode; 
         // obtain a list of dependencies 
         var config = JSON.parse("{" + query("form", node)[0].dataset.config + "}"); 
    
         // require (AMD load) dependencies 
         require(config.deps, function() { 
          // parse ContentPane content when dependencies are resolved 
          dijits = parser.parse(node); 
          console.log(dijits); // an array of instantiated dijits 
         }); 
        }  
    }); 
    ​ 
    

編輯:我剛剛得到這個想法,寫一個自動需要(爲道場< 1.8)僅僅是增加一個短getDependencies()方法,所以你不需要像我在上面的第二個選項提到列出依賴性:

function getDependencies(/*DOMNode*/ containerNode) { 
    var deps = []; 
    query("[data-dojo-type]", containerNode).forEach(function(node) { 
     var dep = node.dataset.dojoType.split(".").join("/"); 
     if(!~array.indexOf(deps, dep)) { 
      deps.push(dep); 
     };    
    }); 
    return deps; 
} 

看到它的jsfiddle工作: http://jsfiddle.net/phusick/hnjWt/

+1

+1用於重寫OP的應用程序邏輯 - 用於開溝dojox.layout.ContentPane.executeScripts :) – mschr

1

您唯一的選擇是設置dojoConfig.async = false或在代碼中的require語句中設置。

由於這個原因,模塊沒有加載; require()不會阻塞 - 雖然它仍在下載模塊),解析器將運行。

運行的這個

require(["dojox/layout/ContentPane", "dojo/domReady!"], function(pane) { 

    var p = new pane({ parseOnLoad: true, executeScripts: true }, 'container'); 
    var content = '<script type="text/javascript">'+ 
     'require('+ 
     ////////////////////////// 
     '{async:false},'+ //////// 
     ////////////////////////// 
     '["dijit/form/Button"]);'+ 
     '<'+'/script>'+ 
     '<div data-dojo-type="dijit.form.Button">Button</div>'; 
    p.set("content", content); 
});​ 
相關問題