简体   繁体   English

如何在已解析的dojo ContentPane中使用dijit require

[英]How to use dijit requires in parsed dojo ContentPane

I am trying to do a simple task. 我正在尝试做一个简单的任务。 This task is to load a HTML containg dijit.Form into a ContentPane . 此任务是将包含dijit.Form的HTML dijit.FormContentPane I don't know which dijits I will need before I load this HTML, but the loaded HTML will contain applicable require 's to load them. 我不知道在加载此HTML之前需要哪些dijit,但是加载的HTML将包含适用的require来加载它们。

So in order to be able to execute the script from loaded HTML I use dojox.layout.ContentPane . 因此,为了能够从加载的HTML执行脚本,我使用dojox.layout.ContentPane However when I set parseOnLoad to true , the parsing takes place before the script execution, so the dijits aren't available when first loading the content. 但是,当我将parseOnLoad设置为true ,解析是脚本执行之前进行的,因此在首次加载内容时不可用dijits。 Also when I try to use onDownloadEnd callback, when this callback is run, the dijits from require 's are still not loaded. 另外,当我尝试使用onDownloadEnd回调时,运行此回调时,仍然不会加载require的dijits。

Only thing I can think of myself is using setTimeout to defer parsing to a time when these scripts will be executed. 我唯一想到的就是使用setTimeout将解析推迟到执行这些脚本的时间。 I don't like this solution however as it may fail from time to time and it would make the application less responsible. 我不喜欢这种解决方案,因为它可能会不时失败,并且会使应用程序的责任感降低。

So how should I perform the parsing so that it happens right after the require statement from loaded HTML is run? 因此,我应该如何执行分析,以使其在加载的HTML的require语句运行后立即发生?

I can see two possible solutions - both with dijit/layout/ContentPane : 我可以看到两个可能的解决方案-都使用dijit/layout/ContentPane

  1. Use Dojo 1.8.0, as the parser supports auto require , it will load dependencies itself as you can see here: http://jsfiddle.net/phusick/vr4h4/ 使用Dojo 1.8.0,因为解析器支持auto require ,它将自动加载依赖项,如下所示: http : //jsfiddle.net/phusick/vr4h4/

  2. Put the list of dependencies somewhere into your form template, eg in data-config attribute of your dijit/form/Form : 将依赖项列表放在表单模板中的某个位置,例如,在dijit/form/Form data-config属性中:

     <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> 

    Set parseOnLoad:false for the dijit/layout/ContentPane , load the template, get the list of dependencies, require them and then in the factory function parser.parse() containerNode of your ContentPane (see it in action http://jsfiddle.net/phusick/QA4gH/ ): dijit/layout/ContentPane设置parseOnLoad:false ,加载模板,获取依赖项列表, require依赖项,然后在ContentPane的工厂函数parser.parse() containerNode中进行操作(请参阅操作http:// jsfiddle。净/ 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 }); } });​ 

EDIT : I just got this idea that writing an auto require (for Dojo <1.8) is just about adding a short getDependencies() method, so you don't need to list dependencies as I mentioned in the second option above: 编辑 :我只是有这样一个想法,编写一个自动需求(针对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;
}

See it working at jsFiddle: http://jsfiddle.net/phusick/hnjWt/ 看到它在jsFiddle上运行: http : //jsfiddle.net/phusick/hnjWt/

Only option you have is to set dojoConfig.async = false or set in the require statements in your code. 您唯一的选择是设置dojoConfig.async = false或在代码中的require语句中设置。

The modules are not loaded for this reason; 由于这个原因,模块没有被加载。 require() does not block - and whilst it is still downloading modules - the parser runs. require()不会阻止-并且尽管它仍在下载模块-解析器仍在运行。

See http://jsfiddle.net/zA9cJ/1/ for running sample of this 有关此示例的运行示例,请参见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);
});​

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM