向backbone视图传递参数

5

我刚开始接触Backbone。我有一个通用视图,可以将集合呈现为带标题的列表。目前我正在将集合和标题传递给渲染方法,但这似乎有点奇怪。是否有更规范的另一种方式?

例如:

var ListView = Backbone.View.extend({
    template: _.template([
        "<div>",
        "<% if (title) { %><h2><%= title %></h2> <% } %>",
        "<% if (items.length > 0) { %>",
        "<ul>",
            "<% items.each(function(item) { %>",
            "<%= itemTemplate(item) %>",
            "<% }); %>",
        "</ul>",
        "<% } else { %><p>None.</p><% } %>",
        "</div>"
    ].join('')),

    itemTemplate: _.template(
        "<li><%= attributes.name %> (<%= id %>)</li>"
    ),

    render: function(items, title) {
        var html = this.template({
            items: items /* a collection */,
            title : title || '',
            itemTemplate: this.itemTemplate
        });

        $(this.el).append(html);
    }
});

var myView = new ListView({ el: $('#target') });
myView.render(myThings, 'My Things');
myView.render(otherThings, 'Other Things');
2个回答

17

你应该在initialize()函数中传递属性:

initialize: function (attrs) {
    this.options = attrs;
}

所以在这里,你需要将属性作为一个对象传递,像这样:

new MyView({
  some: "something",
  that: "something else"
})

现在你可以通过this.options访问到你传入的值。

console.log(this.options.some) # "something"
console.log(this.options.that) # "something else"
为了传递一个集合,我建议创建一个父视图和一个子视图:
var View;
var Subview;

View = Backbone.View.extend({
    initialize: function() {
        try {
            if (!(this.collection instanceof Backbone.Collection)) {
                throw new typeError("this.collection not instanceof Backbone.Collection")
            }
            this.subViews = [];
            this.collection.forEach(function (model) {
                this.subViews.push(new SubView({model: model}));
            });
        } catch (e) {
            console.error(e)
        }
    },
    render: function() {
        this.subViews.forEach(function (view) {
            this.$el.append(view.render().$el);
        }, this);
        return this;
    }
});

SubView = Backbone.View.extend({
    initialize: function () {
        try {
            if (!(this.model instanceof Backbone.model)) {
                throw new typeError("this.collection not instanceof Backbone.Collection")
            }
        } catch (e) {
            console.error(e);
        }
    },
    render: function () {
        return this;
    }
});

testCollection = new MyCollection();
collectionView = new View({collection: testCollection});
$("body").html(collectionView.render().$el);

你应该始终处理集合的模型,而不仅仅是集合中的数据。


我想用这种方法,为每个集合创建一个新视图,而不是重复使用同一视图来处理多个集合。这很有道理。 - sprugman
我有点困惑:为什么你要用Backbone.Model来构建视图而不是Backbone.View? - sprugman
笔误,应该使用 Backbone.View - Austin
好的,现在更有意义了。为了显示<li>item.name</li>创建一个整个subView类对我来说似乎过于繁琐,但我理解你的想法,对于更复杂的情况这肯定是有意义的。 - sprugman
相信我,这是编写集合视图的最有效方法。通过这种方式,您可以将“事件”对象委托给与该模型相关的“SubView”。对于每个动态视图,都应该有一个模型。 - Austin
显示剩余4条评论

2

在渲染视图时,您应该拥有一个模型并访问模型的属性。

var myModel = new Backbone.Model();

myModel.set("myThings", myThings);
myModel.set("myOtherThings", myOtherThings);

var myView = new ListView({ model: myModel });

这是一组模型的视图。我想我可以在集合周围有一个包装模型,但那似乎是不必要的结构。 - sprugman
您可以同时传递一个模型和一个集合。 - algiecas
如何在视图中访问模型?是这样的 this.model 吗?我之所以问这个问题,是因为例如如果我传递:ListView({soption:true,model:myModel}),那么我可以使用 this.options.soption 访问 soption,但是模型是否也可以使用 this.options... 访问呢? - user1102171
回答自己的评论:在 Backbone 视图内,可以使用 this.options.model 访问模型。 - user1102171

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接