arturadib / agility

Javascript MVC for the "write less, do more" programmer
http://agilityjs.com
MIT License
542 stars 70 forks source link

Implemented 1-way binding of multiple attributes per tag with tests and full hierarchical inheritance of any controller event #34

Closed tristanls closed 13 years ago

tristanls commented 13 years ago

Implemented 1-way binding of multiple attributes per tag with tests

I think this implements issue #16

We had a need for setting multiple attributes and the tag value. For example:

<option value="special.format.value">Special Format Label</option>

This commit extends the data-bind functionality so that the above could be written as:

var op = $$( 
  { value: "special.format.value", label: "Special Format Label" },
  '<option data-bind="label, value value"></option>' );

Furthermore, we can now implement external stylesheets a little easier as such:

var lbl = $$( {}, <span data-bind="label, class cls"/>' );
var errorLabel = $$( lbl, { cls: "error" } );
var normalLabel = $$( lbl, { cls: "normal" } );

note: the non-attribute data-bind needs to be first if it exists, rest is comma separated attribute variable pairs

Implemented full hierarchical inheritance of any controller event

This additional pull request ( starting with 8a7a56b ) implements hierarchical inheritance of controller events. It allows us greater reuse of agility objects and enables construction by composition. Here's what that means:

var label = $$( {}, '<span data-bind="label"/>' );

var labeledElement = $$( {}, '<div/>', {
  'create': function() {
    var lbl = $$( label, { label: this.model.get( 'label' ) } );
    this.append( lbl );
  }
});

var labeledValue = $$( labeledElement, {
  controller: {
    '~create': function() {  // <- notice the '~' syntax, this is *hint* to the framework to extend instead of overriding
      var value = $$( label, { label: this.model.get( 'value' ) } );
      this.append( value );
    }
  }
});

var myLabeledValue = $$( labeledValue, { label: "myLabel", value: "myValue" } );

<div><span data-bind="label">myLabel</span><span data-bind="label">myValue</span></div>
tristanls commented 13 years ago

So now that I implemented this in trigger(), I'm thinking that this will be less efficient. Reason being is that the inherited trigger stack will now be built every time when an event is triggered. 'create' only happens at construction time, but if we fire off 5 custom events, and they inherit, we will be building the trigger stack per each event. On the other hand, the previous implementation using rewriting the object controller structure at construction time, would simply execute already built chain 5 times, and not have to build it every time.

Additionally, I wasn't able to see how I could get away from using closures in order to capture the appropriate context, so I think my original implementation is "more better" based on the above reasoning.

arturadib commented 13 years ago

All done, thanks Tristan!