0

我正在尝试做一个简单的任务。此任务是将包含的 HTML 加载dijit.FormContentPane. 在加载此 HTML 之前,我不知道需要哪些 dijit,但加载的 HTML 将包含适用require的 's 来加载它们。

因此,为了能够从加载的 HTML 中执行脚本,我使用dojox.layout.ContentPane. 但是,当我设置parseOnLoad为时true,解析发生脚本执行之前,因此第一次加载内容时 dijit 不可用。另外,当我尝试使用onDownloadEnd回调时,运行此回调时,require仍然没有加载来自 's 的 dijit。

我唯一能想到的就是setTimeout将解析推迟到执行这些脚本的时间。但是,我不喜欢这种解决方案,因为它可能会不时失败,并且会使应用程序的责任感降低。

那么我应该如何执行解析,以便在require加载的 HTML 语句运行后立即发生解析?

4

2 回答 2

2

我可以看到两种可能的解决方案 - 两者都有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() containerNode您的工厂函数中ContentPane(在操作中查看它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
            });
        }      
    });
    ​
    

编辑:我刚刚想到写一个自动要求(对于 Dojo <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/

于 2012-09-22T20:28:12.307 回答
1

您唯一的选择是设置 dojoConfig.async = false 或在代码中的 require 语句中设置。

由于这个原因,模块没有被加载;require() 不会阻塞——当它仍在下载模块时——解析器运行。

有关此运行示例,请参见http://jsfiddle.net/zA9cJ/1/

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);
});​
于 2012-09-22T19:06:00.513 回答