BaseObservable — Extracting lifecycle and attribute change observability from Y.Base#168
BaseObservable — Extracting lifecycle and attribute change observability from Y.Base#168ericf wants to merge 20 commits into
Y.Base#168Conversation
Move the observablility of `Y.Base`'s lifecycle and attribute changes into `Y.BaseEvents`, an extension for `Y.BaseCore`.
There was a problem hiding this comment.
Having this method on Y.Base may affect the ability to mix in Y.BaseEvents into a Y.BaseCore subclass at runtime.
|
@sdesai This is the initial work I've done to extract |
|
I wonder if this is similar to the DT class extensions, in that I included |
There was a problem hiding this comment.
I'm pretty sure _ATTR_CFG and _ATTR_CFG_HASH should be aggregated by Y.Base.create() and Y.Base.mix(). Looking at Y.Base._buildCfg, I see the following:
Base._buildCfg = {
custom: {
ATTRS: function (prop, r, s) { /* ... */ },
_NON_ATTRS_CFG: arrayAggregator
}
};It seems natural to add _ATTR_CFG and possibly _ATTR_CFG_HASH to this set. This way, you could mix Y.Base.Events (which wants to add things to _ATTR_CFG) to a Y.Base.Core subclass at runtime via Y.Base.mix().
Since _ATTR_CFG_HASH depends on _ATTR_CFG being fully aggregated, it would be brittle to rely on object property order for its function to be called after _ATTR_CFG's :-/
There was a problem hiding this comment.
The implementation I ended up with is in d92409c
This allows BaseCore to be the root Base-based superclass enabling the
ability to mix in BaseEvents at runtime. The following is now possible:
Y.Foo = Y.Base.create('foo', Y.BaseCore, []);
// And...
Y.Bar = Y.Base.create('bar', Y.BaseCore, [Y.BaseEvents]);
// Or...
Y.Baz = Y.Base.create('baz', Y.BaseCore, []);
Y.Base.mix(Y.Baz, [Y.BaseEvents]);
|
@sdesai the idea is to try to use this feature on the new mojito prototype we are building during the current cycle :) |
|
Will take a look this week. |
|
Sorry about the delay looking into this. I'm just going to put it in the next sprint, so it gets done. |
Conflicts: src/base/base-base.properties src/base/build.xml src/base/tests/base-tests.js
|
Updated the Todos list in the Pull Request description based on feedback from @sdesai when we had a code review. |
This moves the protected `_protectAttrs()` method to a static utility method on `Y.AttributeCore` and `Y.Attribute`.
The reduces dependencies of BaseEvents, but does introduce the fact that mixing BaseEvents into BaseCore does not equal the functionality of Base. This is because Base now explicitly mixes in AttributeExtras.
A Base/BaseCore-based class will now compute its `_ATTR_CFG_HASH` on demand, when it is needed. If an extension is mixed in via `Y.Base.mix()`, then the cached hash will be nulled-out.
This renames: * Y.AttributeEvents -> Y.AttributeObservable * attribute-events -> attribute-observable
This renames: * Y.BaseEvents -> Y.BaseObservable * base-events -> base-observable
|
Note: Travis is lying, this does actually pass all tests, I just decided against checking in the build files for the sake of the diff. |
|
I'm not sure why my scripts aren't picking it up, I'll ping the Travis |
|
It has been determined that the API documentation anomalies are issues with YUIDoc that will be reported and fixed there. |
|
I am going to merge this into the |
|
This has been merged in |
This extracts
Y.BaseObservable, an extension forY.BaseCore, fromY.Base.By extracting the lifecycle and attribute change observability features, BaseCore subclasses have the potential to mix these features back in at runtime. These changes (and probably more) are needed to create the
Y.Model.Baseclass andY.Model.Observableextension.I ran the
baseunit test and they all pass; additionally, I ranapp's and a few other higher-level components to make sure I didn't introduce any gaps or regressions.Running Locally
I explicitly did not commit the build files or the Loader metadata update, when trying out these changes locally, do the following:
Todos
There are several things that still have to be done before this is merged in. Many of these came up in a code review of this Pull Request.
Determine if `Y.BaseObservable` can be mixed into a `Y.BaseCore` subclass at runtime.Try implementing `Y.Model.Base` and `Y.Model.Observable` on this structure.Move Attribute's `_protecteAttrs()` prototype method to a static utility method on the `Y.Attribute` constructor function.
-Have `Y.BaseObservable` not mix `Y.Attribute` as a whole, instead:
-`Y.Base` will itself mix-in `Y.AttributeExtras` before `Y.BaseObservable`.Investigate whether `Y.Model.Base` should itself mix-in `Y.AttributeExtras`.
-Remove `Base._buildCfg = ` from `base-build`:Create a separate object used for Base's config that's a copy of BaseCore's.Move the `_ATTR_CFG_HASH` computation into `base-build`.Naming: I kind of like "observable" better, e.g. `Y.BaseCore` and `Y.BaseObservable`. This should trickle down to `Y.AttributeObservable` too.Figure out correct yuidoc tags to use to make the API docs right (possibly a bug in yuidocjs).