0

伙计们

我们的项目规模迅速扩大,我想成为一名优秀的 JS 公民,并在为时已晚之前实施测试。我们正在使用带有 Backbone Layoutmanager 和 Handlebars 模板的 Backbone 创建我们的前端,我已经阅读了一些 关于如何使用Jasmine和 Jasmine-Jquery 和Sinon测试 Backbone 驱动的应用程序的优秀博客文章,所以我决定去吧。

但是,我们的设置有点不典型,因为我们使用 RequireJS 模块,使用 Layoutmanager 增强 Backbone,以及预编译 Handlebars 模板。我们正在按照这些库的创建者的建议异步预编译模板,在我意识到任何类型的异步 jQuery/Ajax 调用都不起作用之前,我花了一整天的大部分时间敲打我的脑袋使用 Jasmine 运行应用程序。试图使$.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);
    }

});

解决方案是将异步逻辑包装在runs其中waitFor

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

如果还不够公平,希望其他人从这篇文章中学到东西。

4

1 回答 1

0

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

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

done(JST[path]);然后可以删除该行。

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

接受这个作为答案。

于 2013-01-16T15:51:34.453 回答