1
votes

I have a typical structure of a collection holding models.

In the view, each object has an 'edit' button, that should desactivate all 'edit' buttons of other objects.

I wonder what is the best practice of doing that. Thanks!!

2

2 Answers

2
votes

You could add a property editable on your models that is default set to true. Then when you click the 'edit' button on one of the views, you could loop through all the models of the other views and set editable to false. On the view you would listen to model changes, and re-render the view. If editable is false you would disable the edit button.

0
votes

Ok, so I came up with the following approach:

Assume that model has a property status, and when it is modified to active I want to hide the edit button in other entries (or simply disable it).

My collection view listens to a change in a model:

initialize: function(){
  this.listenTo(this.collection, "change:status", this.triggerEditable);
},

The listener callback looks like that:

triggerEditable: function(obj){
    var triggerValue = null;

    // I am interested in a status which became 'active' or stopped being 'active'
    if (obj.get("status") == 'active' && obj.previous("status") != 'active') {
        triggerValue = "editable:false";
    } else if (obj.get("status") != 'active' && obj.previous("status") == 'active') {
        triggerValue = "editable:true";
    }

    // for any other status change - return
    if (!triggerValue) return;

    // trigger is fired for all other objects in the collection
    _.each(obj.collection.without(obj),function(otherObj) {
        otherObj.trigger(triggerValue);
    });
}

So, when one object becomes active or stop being active, edidable:false or edidable:true are triggered for all other entries. All I need to do is to add to the model view initializer a listener:

this.listenTo(this.model, "editable:false", this.disableEdit);
this.listenTo(this.model, "editable:true", this.enableEdit);

Here I guess I could combine these two lines into one, first by listening to the editable namespace (how??) and then by passing an argument to the function (again, how exactly?).

From here it is straight forward - implement the listener callback:

disableEdit: function() {
    var e = this.$el.find('button.edit')
    e.attr('disabled','disabled');
}

If somebody has something to add or to make this solution nicer, I will be glad to hear. Anyway, hope it will be helpful to others!!