【问题标题】:Passing arguments to a backbone view将参数传递给主干视图
【发布时间】:2012-07-09 07:39:30
【问题描述】:

刚刚开始使用 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');

【问题讨论】:

    标签: javascript collections backbone.js views


    【解决方案1】:

    您应该在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);
    

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

    【讨论】:

    • 我想通过这种方法,我正在为每个集合创建一个新视图,而不是对多个集合重用同一个视图。有道理。
    • 其实...如果我只是在实例化时传入一些选项,我认为我什至不需要创建初始化方法——它会自动将传入的选项放入构造函数中一个选项对象。
    • 然后,如果我不想为每个集合创建一个新视图,我可以执行 myViewInstance.options.some = 'New Value'...
    • 这个方法是用来传入选项的,仅此而已。如果您要传入一个集合,那么为集合本身创建一个视图以及为该集合中的每个模型创建一个子视图会更有效。
    • 我在答案中添加了您应该处理集合及其视图的方式
    【解决方案2】:

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

    var myModel = new Backbone.Model();
    
    myModel.set("myThings", myThings);
    myModel.set("myOtherThings", myOtherThings);
    
    var myView = new ListView({ model: myModel });
    

    【讨论】:

    • 这是模型集合的视图。我想我可以在集合周围有一个包装模型,但这似乎是不必要的结构。
    • 可以同时传递一个模型和一个集合。
    • 如何访问视图内的模型。是这个.model。我问这个是因为例如如果我通过:ListView({soption:true,model:myModel}),那么我可以使用:this.options.soption 访问 soption,但随后模型也可以使用 this.options 访问... .?
    • 回答我自己的 cmets:可以在主干视图中使用 this.options.model 访问模型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 2018-01-08
    • 2011-10-07
    • 2011-06-16
    • 1970-01-01
    相关资源
    最近更新 更多