This debate has been sparked by the work of @tristanls, who implemented the extend (~
) syntax for controllers.
Originally, Agility tried to stick to a differential inheritance paradigm. This meant that all properties of Agility objects were passed on to their descendants as prototype methods, except when overridden by the children:
// parent defines controller
var parent = $$({}, '<div/>', {
'create': function(){}
});
// child redefines controller of parent
var child = $$(parent, {}, {}, {
'create': function(){... new controller ...}
})
That was not the desired behavior, mainly because there would be no way to extend previously defined controllers. So @tristanls proposed the new syntax ~
for controllers, which would allow one to keep the previously defined handler create
, and add some more logic to it:
// child *extends* controller of parent
var child = $$(parent, {}, {}, {
'~create': function(){... more logic in addition to parent's...}
})
Then Darren Mason pointed out that a similar issue arises with CSS styles:
// parent defines style
var parent = $$({}, {format:'<div/>',
style:'& {color:red}'
});
// child redefines style, losing the color above
var child = $$({}, {format:'<div/>',
style:'& {float:right}'
});
Again, @tristanls proposed a similar solution:
// child *extends* style, keeping color from parent
var child = $$({}, {format:'<div/>',
'~style':'& {float:right}'
});
This seems to reveal a pattern - whenever some properties can be extended, it seems like the desired default behavior is to extend, and not override. This includes CSS styles and controllers. (There doesn't seem to exist a way to naturally extend models and formats, so these would have to be overridden by default).
So I am considering the possibility to make extend the default behavior for controllers and styles, and to introduce a new syntax !
to allow children objects to override inherited properties, e.g.
// parent defines style
var parent = $$({}, {format:'<div/>',
style:'& {color:red}'
});
// extend style (default behavior), keeping color above
var child = $$({}, {format:'<div/>',
style:'& {float:right}'
});
// redefine style, losing the color above
var child2 = $$({}, {format:'<div/>',
'!style':'& {float:right}'
});
The pros and cons I can see are:
- Pros: More compact syntax for desired behavior
- Cons: Non-uniform behavior, that is, models and formats are treated differently from styles and controllers
What do you think?