New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
adds custom attributes #257
Conversation
Left some comments on individual commits. Generally it looks good to me but I'm afraid that I still don't have the full picture of the framework in my head to asses all the consequences of this change so it would be great to hear from @b-laporte |
var customHandlers = hsp.getCustomAttributes(nm); | ||
if (customHandlers && customHandlers.length > 0) { | ||
for (var j = 0; j < customHandlers.length; j++) { | ||
this._customAttributesHandlers.push({name: nm, handler: customHandlers[j].handler}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If refreshAttributes
is called several times (it is called each time an attributes changes), the same handler will be present several times in this._customAttributesHandlers
and the cleanHandlers
method will be called several times for the same node and same handler in $dispose
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I realized that too and I'll improve it.
As discussed with @Mlaval, I would prefer having a slightly different interface for custom attributes. |
Thanks for the comments @divdavem and @PK1A, I've amended the PR to do the changes, except for the API change suggestion that we should discuss first. In addition, I've delayed the initial handling of custom attributes, it is now done after all node instances have been created. This way the handler can always access children and siblings. |
Finally implemented this feature as suggested by @divdavem , i.e. one instance of the handler is created per node where the custom attribute is added, and its lifecycle relies on $constructor, setValue and $dispose.
On top of the test and the gesture refactor, I also challenged this code by implementing a dropdown custom attribute for https://github.com/ariatemplates/hashspace-bootstrap It does work but it is limited and not very developer friendly. This raises questions about the API offered by the node instance, and the way attributes (class, model, ...) are managed within Hashspace. |
@Mlaval @divdavem @PK1A We should not force people to use it. They should be free to use whatever they want. For example, relying on We should implement this feature with a dual approach:
It could be really much simpler, and should be more user friendly and generic. |
* Registers a set of custom attributes with a matching handler. | ||
* @param {Array|String} names the name of the attributes. | ||
* @param {Object} handler the attribute handler klass, which can implement: | ||
* - $constructor(nodeInstance, callback): used to dispose the handler instance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copy/paste issue: the constructor is probably not used to dispose the handler instance.
@benouat As far as I can see, the feature does not really rely on the klass utility. var MyHandler = function (nodeInstance, callback) {
// do something when the node is created (if needed)
};
MyHandler.prototype.setValue = function (name, value) {
// do something when the value is set
};
MyHandler.prototype.$dispose = function () {
// do something when the node is destroyed
}; And if the |
@benouat Do you mean we should remove the |
@divdavem you're right, I forget about these ones, but we might also change that. We should maybe open another topic on that specific subject |
Added an independent handler for class attributes, which also helped improving the whole feature. |
Simplified a lot the class custom attributes as class order is not that important in an element, unless such rules are being written:
@benouat with the new code, using classList could remove one of the 2 split() left. I suggest to keep it simple for now. |
This PR also implements the refactoring that was discussed last week. In terms of API, this PR introduces 2 new methods on the custom attribute handler:
It also introduces a few methods on EltNode that enables a custom attribute to be powerful without knowing the internals of EltNode:
|
7089149
to
c3dedb4
Compare
I might be wrong, but I clearly don't see the Let's consider this sample <div class="{ { 'class1': expression, 'class2': expression } | tokenList }"></div> Where we could have this simple function tokenList(obj) {
var tokens = [];
for (var key in obj) {
if (obj[key]) {
tokens.push(key);
}
}
return tokens.join(' ');
} I don't see the custom behavior. Am I completely wrong on that one ? |
Well we could decide to implement it this way, it would work. One drawback I see is that we'd loose one of the feature of the custom attributes: carefully updating the class attribute without overwriting it each time. This means that classes injected by others (e.g. a custom attribute) would be lost. |
c3dedb4
to
5910a88
Compare
5910a88
to
377c5f4
Compare
377c5f4
to
2ccb3fb
Compare
2ccb3fb
to
d84f8b4
Compare
A first implementation of custom attributes.
To demo it, gestures have been made fully independent and optional module.
Before adding documentation and sample, a review is needed please.