1

据我所知,Backbone.js 视图代表 DOM 元素。我从现有的 DOM 中获取它或在el属性中动态创建它。

就我而言,我想通过 AJAX 请求从服务器获取它,因为我使用的是 Django 模板并且不想将所有内容都重写为 JavaScript 模板。

所以我定义el了执行 AJAX 请求的函数。

el: function() {
    model.fetch().success(function(response) {
        return response.template
    })
}

当然,它不起作用,因为 AJAX 请求是异步执行的。

这意味着我没有el属性,events也没有工作。我可以修复它吗?

也许 Backbone.js 框架不适合我的需求?我想使用它的原因是有一些代码结构。

PS 我是 Backbone.js 的新手。

4

2 回答 2

2

从另一个视图执行您的 ajax 请求,或者直接在页面加载后直接使用 jquery,并且在您下载模板之后,然后使用正确的 id/el 或其他任何内容(取决于您存储获取的 ajax 的位置)实例化您的主干视图类模板)。根据您的用例,这可能是也可能不是明智的方法。

另一种可能更典型的方法是使用一些占位符元素(例如“正在加载”或其他)设置您的视图,然后触发 ajax,并在检索到更新的模板后,相应地更新您的视图(替换带有您请求的实际模板的占位符)。

当/如果您使用新的/其他 DOM 元素更新视图时,您需要调用视图的delegateEvents方法将事件重新绑定到新元素,请参阅:

http://backbonejs.org/#View-delegateEvents

于 2013-02-22T15:50:15.263 回答
2

我遇到了类似的要求。在我的实例中,我正在运行 asp.net 并希望从用户控件中提取我的模板。我建议的第一件事是研究 Marionette,因为它可以让您免于在 Backbone 中编写大量样板代码。下一步是覆盖模板的加载方式。在本例中,我创建了一个使用 Ajax 从服务器检索 HTML 的函数。我找到了这个函数的一个例子,他们用它来拉下 html 页面,所以我做了一些修改,所以我可以发出 MVC 类型的请求。我不记得我是从哪里找到这个想法的;否则,我会在这里给出链接。

function JackTemplateLoader(params) {
    if (typeof params === 'undefined') params = {};
    var TEMPLATE_DIR = params.dir || '';

    var file_cache = {};

    function get_filename(name) {
        if (name.indexOf('-') > -1) name = name.substring(0, name.indexOf('-'));
        return TEMPLATE_DIR + name;
    }

    this.get_template = function (name) {
        var template;
        var file = get_filename(name);
        var file_content;
        var result;
        if (!(file_content = file_cache[name])) {
            $.ajax({
                url: file,
                async: false,
                success: function (data) {
                    file_content = data; // wrap top-level templates for selection
                    file_cache[name] = file_content;
                }
            });
        }
        //return file_content.find('#' + name).html();
        return file_content;
    }

    this.clear_cache = function () {
        template_cache = {};
    };

}

第三步是重写 Marionette 加载模板的方法。我在 app.addInitializer 方法中做到了这一点。在这里,我正在初始化我的模板加载器并将其目录设置为路由处理程序。因此,当我想加载模板时,我只需在视图中设置模板:“templatename”,Backbone 将从 api/ApplicationScreens/templatename 加载模板。我还重写了我的模板编译以使用 Handlebars,因为 ASP.net 对 <%= %> 语法没有印象。

    app.JackTemplateLoader = new JackTemplateLoader({ dir: "/api/ApplicationScreens/", ext: '' });
    Backbone.Marionette.TemplateCache.prototype.loadTemplate = function (name) {
        if (name == undefined) {
            return "";
        } else {
            var template = app.JackTemplateLoader.get_template(name);
            return template;
        }
    };
    // compiling
    Backbone.Marionette.TemplateCache.prototype.compileTemplate = function (rawTemplate) {
        var compiled = Handlebars.compile(rawTemplate);
        return compiled;
    };
    // rendering
    Backbone.Marionette.Renderer.render = function (template, data) {
        var template = Marionette.TemplateCache.get(template);
        return template(data);
    }

希望这会有所帮助。我一直在开发一个大型动态网站,并且进展顺利。我一直对使用 Marionette 和 Backbone.js 的整体功能和流程感到惊讶。

于 2013-03-08T13:20:07.580 回答