如何从路线渲染视图?

How to render a view from a route?

我的应用程序包含两个带有模板、路由器、模型和集合的视图。

root
 js
  collections
   -collection.js
  models
   -model.js
  routers
   -router.js
  templates
   -add_item.html
   -list.html
  views
    -add_item.js
    -list.js
index.html

router.js 中,我正在尝试导航到子视图。

define([
    'jquery',
    'backbone',
    'views/item'
], function($, Backbone, ItemView) {
    'use strict';

    return Backbone.Router.extend({
        routes: {
            '': 'list',
            'list/add': 'addItem',
            'list/edit/:id': 'editItem'
        },

        addItem: function() {
            new ItemView();
        }
    });
});

通过查看调用堆栈,我发现我的路由器触发了。但是我的子视图的模板没有初始化。

item.js代码:

return Backbone.View.extend({
    template: _.template(itemTemplate),

    events: {
        'click #save': 'saveItem',
        'click #cancel': 'cancel'
    },

    initialize: function() {
        this.render();
    },

    render: function() {
        this.$el.html(this.template);
        return this;
    }
});

下划线的 _.template

Underscore _.template function takes a template string as argument (and optionally a settings object) and returns a new pre-compiled template function which can take an object as an argument.

template: _.template(itemTemplate), // this returns a function, which is fine here.

这一行没问题,但下面一行把返回的函数作为HTML内容:

this.$el.html(this.template); // a function reference as HTML?!

需要调用预编译模板函数获取字符串:

this.$el.html(this.template());

Backbone 视图渲染

现在视图的默认根元素 (el) 已正确填充模板内容。

<div>The div element is the default root element, this text is the template</div>

但是一旦呈现模板,页面中的视图元素仍然。要使其成为页面的一部分,您可以:

  • 将视图的 el 手动放入路由器中的另一个元素中

    addItem: function() {
        var view = new ItemView();
        $("#content").html(view.render().el);
    }
    

    我把 view.render() 放在这里是因为 initialize 中的渲染不是我的首选模式,因为它限制了视图的重用。但这实际上取决于视图的用途。

  • selector string 或元素传递给视图的 el 构造函数选项

    new ItemView({ el: '#the-view-element-id' });
    
  • 使用硬编码创建视图 el 属性 (这可以被上面的 el 选项覆盖)

    Backbone.View.extend({
        el: '#the-view-element-id',
        /* ... */
    

默认路线

如果你想默认使用 list 路由,你可以像这样制作 routes 对象:

routes: {
    'list/add': 'addItem',
    'list/edit/:id': 'editItem'
    // catch-all (default) route at the end
    '*anything': 'list',
},

附加信息: