-
Notifications
You must be signed in to change notification settings - Fork 180
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
Setting prop using Boolean (to trigger prop over attribute) always sets true #426
Comments
It's kind of costly to always check for boolean. Is it really necessary to create Boolean objects? |
I'm not sure if the cost of the check is that great, but it is additional code to compile and ship. There is a cost to allocating the I think a more promising approach would be to customize the behavior as described here: http://google.github.io/incremental-dom/#setting-values |
For our project, we opted to change the default behavior of incremental-dom
to always assign boolean primitives to the property.
If you want to assign the attribute, you just have to convert to a string
literal first. If you want to assign a string property, you just use "new
String()".
|
Thank you all for the ideas. I ended up making typeof boolean always use setProp, the same way typeof object and typeof function already do. This introduces a typeof check, but it's less costly than constructing the Boolean during the render plus doing an instanceof on the other side. The customizing behavior seems like a nice idea, but I worry about bugs. If the library behaves differently from project to project in sneaky ways depending on if the same hooks are setup I suspect there will be tricky to diagnose problems from sharing code or practices. |
I've been playing around with this a bit more. The patch I'm using (based on ewinslow's comment) adds some code to applyAttributeTyped, changing...
to...
This check is very inexpensive, requires no object construction on the calling side and solves the general case of elegantly setting a boolean as a property. It's also easy to document this behavior - just as we already document the same behavior for objects and functions. The alternative suggested is something like this:
This is a bit complex just to get standard HTML elements to behave as expected. Another problem with hooks is that it introduces potential conflicts when used with other types of elements, such as SVG or shadow-dom, which either have non-boolean attributes or properties with similar names or have boolean attributes or properties not explicitly listed - or both. Are we sure it's not worth adding the boolean typeof check to the core library to resolve this problem in a simple, general and consistent way? |
We cannot change to use let expanded = false; // This variable is set to a boolean value at some point.
...
// It now gets set as an attribute, and converted to a string.
elementOpen('div', null, null, 'aria-expanded', expanded); This cannot be set as a property and changing this will break existing users in a way that may not be easy to detect. I think for some uses this might not be a big concern, or they might want to have another way around like: let expanded = false;
...
elementOpen('div', null, null, 'aria-expanded', toString(expanded)); or automatically do that a higher level construct that wraps |
@sparhami It seems like the main reason this can't be changed is for backwards compatibility reasons. There is a very clear and cheap (and I'd argue, more correct) solution, which is to use the string value:
Or another case, where you just need attribute presence:
But setting-boolean-properties have much more painful workarounds. I really think setting properties for booleans is the more intuitive behavior here. All code that assumes otherwise can be trivially changed to use strings today and still work fine. But if it's just too much trouble, then I totally get that... |
Using an Object form to trigger prop over attribute setting doesn't work with Boolean objects, because they always resolve to true when applied to boolean DOM properties expecting native booleans, such as checkbox.checked.
a = new Boolean( false );
console.log( !!a ); // outputs true
console.log( a.valueOf() ); // outputs false
By adding something like this to the inside of setProp, this can be easily resolved.
The text was updated successfully, but these errors were encountered: