Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/477.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用主干Layoutmanager预编译用于Jasmine测试的把手模板_Javascript_Unit Testing_Templates_Backbone.js_Jasmine - Fatal编程技术网

Javascript 使用主干Layoutmanager预编译用于Jasmine测试的把手模板

Javascript 使用主干Layoutmanager预编译用于Jasmine测试的把手模板,javascript,unit-testing,templates,backbone.js,jasmine,Javascript,Unit Testing,Templates,Backbone.js,Jasmine,各位 我们的项目规模正在快速增长,我想成为一名优秀的JS公民,在一切都为时已晚之前实施测试。我们正在使用主干网和主干网布局管理器以及把手模板等创建前端,我已经阅读了关于如何使用Jasmine Jquery和测试主干网驱动的应用程序的博客文章,所以我决定进行这项工作 然而,我们的设置有点非典型,因为我们使用的是RequireJS模块,使用Layoutmanager扩展主干,以及预编译把手模板。我们正在由这些库的创建者异步地预编译模板,我花了一整天的时间才意识到,如果使用Jasmine运行应用程序,

各位

我们的项目规模正在快速增长,我想成为一名优秀的JS公民,在一切都为时已晚之前实施测试。我们正在使用主干网和主干网布局管理器以及把手模板等创建前端,我已经阅读了关于如何使用Jasmine Jquery和测试主干网驱动的应用程序的博客文章,所以我决定进行这项工作

然而,我们的设置有点非典型,因为我们使用的是RequireJS模块,使用Layoutmanager扩展主干,以及预编译把手模板。我们正在由这些库的创建者异步地预编译模板,我花了一整天的时间才意识到,如果使用Jasmine运行应用程序,任何类型的异步jQuery/Ajax调用都不会起作用。 试图使
$.ajax(…)
调用与
async:false
同步,但没有做到这一点,深入研究Layoutmanager JS源代码,我发现这一切都是异步进行的

所以不管怎样,这就是我最终如何使预编译工作成功的原因:

Backbone.LayoutManager.configure({
    manage: false,

    prefix: "app/templates/",

    fetch: function(path) {
        var done;
        var that = this;

        // Concatenate the file extension.
        path = path + ".html";

        runs(function() {
            if (!JST[path]) {
                done = that.async()

                return $.ajax({ url: app.root + path, async: false }).then(
                    //Successhandler
                    function(contents) {
                        JST[path] = Handlebars.compile(contents);
                        JST[path].__compiled__ = true;
                        done(JST[path]);
                    },
                    //Errorhandler
                    function(jqXHR, textStatus, errorThrown) {
                        //Feil ved lasting av template
                        //TODO logg feil på en eller annen måte
                    }
                );
            }
            // If the template hasn't been compiled yet, then compile.
            if (!JST[path].__compiled__) {
                JST[path] = Handlebars.compile(JST[path]);
                JST[path].__compiled__ = true;
            }
        });

        waitsFor(function() {
            return done;
        }, "loading template", 500);
        return JST[path];
    },

    // Override render to use Handlebars
    render: function(template, context) {
        return template(context);
    }

});
解决方案是将异步逻辑包装在
运行
等待

现在回答问题: 我认为这不是一个最佳的解决方案,因为它迫使我复制app.js来包装异步调用。有没有更好的办法解决这个问题


如果没有足够的公平,希望其他人能从这篇文章中学习。

不幸的是,我还没有找到一个可以避免重复app.js的解决方案。但该文件很少更改,因此它不是一个真正的问题。 不过,我对上面的异步处理做了一些改进,使其更加健壮:

    waitsFor(function() {
        return JST[path] && JST[path].__compiled__;
    }, "loading template", 1000);
    return JST[path];
done(JST[path])

现在测试运行更加稳定,以前它们有时会由于模板加载不正确而失败


接受这个作为答案。

最近也有类似的问题,不确定您是否看到了:我最终使用了它的一个变体,但将我的所有模板作为开发过程的一部分进行了预编译,因此它们都在一个文件(编译的templates.js)中,并通过require作为依赖项加载。在返回val之前,您确实需要设置compiled=true。如果由于任何原因没有将任何文件添加到预编译包中,您可以保留单独的文件ajax编译以防故障。