petermichaux / maria

The MVC framework for JavaScript applications. The real MVC. The Smalltalk MVC. The Gang of Four MVC.
BSD 2-Clause "Simplified" License
764 stars 51 forks source link

plugin for events with type "change:name" #50

Open petermichaux opened 11 years ago

petermichaux commented 11 years ago

Occasionally, views need more fine-grained notification than the coarse-grained change event that usually causes the view to make a complete refresh. For example, a PersonView might want to know only when the PersonModel's name changes and only update the visible name in the display.

The plugin implementation would be

(function() {
    var original = maria.Model.prototype.dispatchEvent;
    return function(evt) {
        var type = evt.type;
        while (type) {
            evt.type = type;
            original.call(this, evt);
            type = type.replace(/\:?[^\:]+$/, '');
        }
    };
}());

With this plugin, a model can have just

setName: function(name) {
    name = '' + name;
    if (this._name !== name) {
        this.name = name;
        this.dispatchEvent({type:'change:name'});
    }
}

which is equivalent to the following without the plugin

setName: function(name) {
    name = '' + name;
    if (this._name !== name) {
        this.name = name;
        this.dispatchEvent({type:'change:name'});
        this.dispatchEvent({type:'change'});
    }
}

When using the plugin, a view that needs fine-grained control will use different modelActions object, for example,

maria.ElementView.subclass(app, 'PersonView', {
    modelActions: {
        'change:name': 'updateName',
        'change:height': 'updateHeight'
    },
    properties: {
        updateName: function() {/* ... */},
        updateHeight: function() {/* ... */}
    }
});