我們的項目是在規模迅速增長,我想成爲一個好的JS-公民,並獲得測試實施之前,爲時已晚。我們正在使用帶Backbone Layoutmanager和Handlebars模板的Backbone創建我們的前端,並且我已閱讀someexcellent關於如何使用Jasmine-Jquery和Sinon使用Jasmine測試骨幹驅動應用的博客文章,因此我決定去那。
但是,我們的設置有點不典型,因爲我們使用RequireJS模塊,使用Layoutmanager擴展Backbone,以及預編譯Handlebars模板。我們正在通過這些庫的創建者異步預編譯模板as is suggested,並且在意識到任何類型的異步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來包裝異步調用。有沒有更好的方法來解決這個問題?
如果還不夠公平,希望別人從這篇文章中學到東西。
最近有一個類似的問題,不知道你是否看到:https://github.com/tbranyen/boilerplate-handlebars-layoutmanager/blob/master/app/app.js我最終使用了這個變種,但有我的所有模板都作爲開發過程的一部分進行了預編譯,因此它們都在一個文件(compiled-templates.js)中,並通過require作爲依賴項加載。在返回val之前,您確實需要設置__compiled__ = true。如果任何文件因任何原因沒有被添加到預編譯包中,您可以保留單個文件的ajax編譯以實現失效保護。 – ldg