-
Notifications
You must be signed in to change notification settings - Fork 27.4k
feat($compile): allow any attribute to use allOrNothing interpolation #8399
Conversation
So we had some discussion about syntax like these, and people tend to not like having special meanings for certain characters, I'm really just bikeshedding here. @btford / @IgorMinar / @petebacondarwin / whoever else, what do you think? I think it's good to be able to request allOrNothing declaratively, but I'm not sure about the syntax. |
I'm not sure about introducing new magical symbols in general. I think I would like |
It doesn't have to be a '!', it could certainly be |
caitp did not add and remove the CLA labels! wat |
Oh GitHub you so crazy |
I am pretty sure that was Igor's script - somehow pretending to be the original poster - you can see it in all the recent PRs. This discussion is similar to the |
How about just making If you really needed your interpolations to support partially undefined interpolations then you could do:
or use a filter
|
Also I don't think it really makes sense for the template writer to define this. |
if (name[name.length - 1] === '!') { | ||
allOrNothing = true; | ||
name = name.substring(0, name.length - 1); | ||
} |
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.
This is weird, if the all-or-nothing
property is checked when performing attribute scanning, then I would expect that this to works too for other directives that have a binding using '@'
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.
It could be supported (depending on the syntax we go with) for @
too --- however lets figure out what the syntax should look like.
Do you have any preferences here @lgalfaso? @rodyhaddad?
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.
Basically, there are two options:
- it can be a suffix for the attribute name, but not a common attribute name (not alpha/numeric), such as
!
,*
,~
, etc. This would allow it to be used after any attribute name. - it could precede the attribute name, and use a fatter/more human readable syntax, such as
ng-attr-all-or-nothing-<name>
--- it's a bit trickier to use this pattern for isolate scope bindings, and it's a bit more code to use this way, and obviously more typing to actually use this way. But it has the benefit of being more readable.
So, I'm not sure which I'd go with --- personally I'd prefer to make things easier for people, but realize that a "magic syntax" could get in peoples ways in some circumstances, rather than making things easier. So we should figure out how this should work.
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.
I would go with a suffix that makes all browsers happy (with the exception of !
as it looks like !=
is a not equals) or with a prefix to the entire directive, this is all-or-nothing-ng-attr-foo="..."
or all-or-nothing-my-binding-param="..."
(where the all-or-nothing
prefix is open to discussion)
have we thought about what @petebacondarwin said? what if allornothing was the default? are there valid cases that would break because of such change? |
alternatively we could make it the default for ng-attr-* though I know that ng-attr does not work for all svg use-cases (I think that this could be fixed though). |
I'm okay with making it the default for ng-attr --- I don't think there are any real valid cases which would break |
updated to remove the magic syntax and make it the default behaviour + added breaking change. LGTY? |
allOrNothing interpolation is now used for ng-attr-*, under all circumstances. This prevents uninitialized attributes from being added to the DOM with invalid values which cause errors to be shown. BREAKING CHANGE: Now, ng-attr-* will never add the attribute to the DOM if any of the interpolated expressions evaluate to `undefined`. To work around this, initialize values which are intended to be the empty string with the empty string: For example, given the following markup: <div ng-attr-style="border-radius: {{value}}{{units}}"></div> If $scope.value is `4`, and $scope.units is undefined, the resulting markup is unchanged: <div ng-attr-style="border-radius: {{value}}{{units}}"></div> However, if $scope.units is `""`, then the resulting markup is updated: <div ng-attr-style="border-radius: {{value}}{{units}}" style="border-radius: 4"></div> Closes angular#8376
PTAL --- are we good to check this in for beta 18? |
@@ -1958,7 +1958,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { | |||
// we need to interpolate again, in case the attribute value has been updated | |||
// (e.g. by another directive's compile function) | |||
interpolateFn = $interpolate(attr[name], true, getTrustedContext(node, name), | |||
ALL_OR_NOTHING_ATTRS[name]); | |||
ALL_OR_NOTHING_ATTRS[name] || allOrNothing); |
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.
This is probably pointless and pedantic but would it be slightly more performant to put the allOrNothing
check first?
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.
I'm not sure this will make a measurable difference, but in some cases putting the boolean first would win (when ng-attr-* is used frequently), in other cases it would lose (when href/src are used frequently). It would depend on the app, I guess
LGTM |
Other than my comment above, LGTM |
thanks~ |
Previously, only a limited set of attributes would use allOrNothing
interpolation. It is now possible to request allOrNothing interpolation by
appending a '!' to the attribute name. This should result in attributes being
removed / not added to the node if their values are undefined, which can
prevent some kinds of errors in SVG elements.
Example:
Closes #8376