The model-view data binding in Titanium’s Alloy is great, but I kept thinking somehow it’s not done right. This is why:
- It pollutes the view with the non-markup
<Collection />
element. - It decides for me when to trigger updating:
Alloy.Collections.myCollection.on('fetch change add remove', function(e) { .. })
- If I somehow need manual updates to I need to copy the above function to my controller.
- It works on collections only.
I think all-in-all it makes to much assumptions and a view shouldn’t be this much involved in controller-like logic.
I would suggest the following changes:
- Get rid of the
<Collection />
element in the view. - Replace
dataCollection
,dataTransform
anddataFilter
attributes withdataBinder
- Replace the generated collection event listener with a method named after the value of the new
dataBinder
attribute - Let the developer call the generated function whenever and passing whatever iteratable object he likes.
- Let the developer do any filtering and transformation before passing the object.
So my view could be:
1 2 3 |
<Table dataBinder="myBinder"> <TableRow title="{title}" /> </Table> |
And in my controller I could do:
1 2 3 4 5 |
Alloy.Collections.instance("items"); Alloy.Collections.place.on("fetch change add remove", function(e) { // Do some filtering and transformation myBinder(this.models); }); |
But also:
1 2 3 4 5 |
myItems = [ { title: 'Item 1' }, { title: 'Item 2' } ]; myBinder(myItems); |
The Alloy docs themselves even quietly mention the 3rd reason I gave why the current implementation is not right. In the part about Backbone Binding it goes:
1 2 3 4 |
library.on('add', function(e){ // custom function to update the content on the view updateFooView(library); }); |
The custom function it asks for is basically what I did in my first controller example, calling the Alloy-generated method that binds data to the view.
Update: In the Alloy Google Group Lead Alloy-developer Tony suggested a best-of-both-compromise for which I opened a JIRA ticket:
- Exposing the Alloy-generated data-binding function.
- Making the function compatible to consume any iterable array or object.
- Having of the option to not automatically add this function as an event listener to model or collection, so you can decide when to call it, using whatever data you like.