1

在我看来,我有这个功能:

saveData: function(){
    this.collection.setSelected(this.collection.where({name : this.$('#projects').val()}));
}

以及我收藏中的相应功能:

setSelected: function(project){
    this.each(function(model){
        model.set({selected: false});
    });
    project[0].set({selected: true});
}

所以,我的问题是为什么我需要访问 Project 数组的第一个元素才能访问实际的模型?难道我做错了什么?

此外,似乎有点 OTT 将集合中的所有模型循环设置为 false,然后将一个设置为 true,这是正确的做事方式吗?

4

3 回答 3

0

让我直截了当,这就是您要实现的目标:

USER SELECTS VIEW ELEMENT
GET NAME FROM ELEMENT
VIEW SETS ALL MODELS SELECTED = FALSE
VIEW SETS MODEL MATCHING NAME SELECTED = TRUE

首先我想说你不需要循环所有模型,因为看起来只有一个模型带有selected=true. 如果是这种情况,您可以简单地使用其他一些可用的下划线集合方法,我也只会将名称值传递setSelected给以在视图中保持简单:

saveData: function(){
    this.collection.setSelected(this.$('#projects').val());
}

setSelected: function(name) {
    this.findfindfunction(model) {
        return model.get('selected');
    }).set('selected', false);

    this.find(function(model) {
        return model.get('name') == name;
    }).set('selected', true);
}

显然,使用该find方法仍然需要在引擎盖下进行一些循环来找到与条件匹配的模型,但它只搜索第一个通过条件的模型,因此where无论如何它都比执行 which loops ever 模型要好。

显然,如果可以选择多个模型,这一切都会崩溃:D

更新

在考虑您的问题多一点后,我认为使用不同的视图架构可能会更好地为您服务。在您描述的情况下,我个人通常使用微视图。即每个模型的小视图。视图标记可能只包含一个复选框,仅此而已。

这意味着在您的主视图中,您可以循环您的集合,并为每个模型创建一个视图,将模型传递给视图,渲染它,并将标记附加到主视图。

通过这种方式,您可以更好地控制与特定模型相关的事件,并且可以轻松地将模型特定值呈现到您的视图中。下面这个简单的视图是一个微视图的简单示例,其中模板仅包含一个复选框和一个标签,或者类似的东西。

var CheckboxView = Backbone.View.extend({
    events: {
        'input[type=checkbox]': 'select'
    },
    render: function () {
        var html = _.template($('#myTemplate'), this.model.toJSON());
        this.$el.html(html);

        return this;
    },
    select: function () {
        this.model.set('selected', true);
    }
});
于 2012-12-04T11:36:54.390 回答
0

为什么我需要访问 Project 数组的第一个元素才能访问实际的模型?

答案是,根据文档where返回匹配模型的数组。因此,您需要使用索引来访问它。

只要只返回一个模型,我认为您用来设置的方法没有任何问题selectedtruewhere

第二个疑问

为什么不使用selectedas创建所有模型false(我假设它会很好)并保持setSelected这样的方法:

setSelected = function(project, value) {

  project[0].set({selected: value});

  // well a better approach would be to define a method in the model saying,
  // select() which sets the attribute, and call it from here with
  // project[0].select(params), but its up to you how you do it.
}

true您可以使用or falsetoselectdeselect任何模型调用相同的方法。

于 2012-12-04T15:11:22.563 回答
0

为什么我需要访问 Project 数组的第一个元素才能访问实际的模型

因为您正在使用where,它返回一个数组。您可以find在这种情况下使用,它返回第一个匹配对象。

this.collection.find(function(x) { return x.get("name") == this.$('#projects').val() });

围绕集合中的所有模型循环似乎有点 OTT

如果您只想一次选择一个模型,那么最好找到选定的模型并取消选择它。就像是:

this.collection.setSelected(this.$('#projects').val());

和:

setSelected: function(name){
    var selected = this.find( function(x) { return this.get("selected") === true } );
    if (typeof selected != "undefined") selected.set("selected", false);

    var newSelected = this.find( function(x) { return this.get("name") === name });
    if (typeof newSelected != "undefined") newSelected.set("selected", true);
}
于 2012-12-04T21:05:04.733 回答