-
Notifications
You must be signed in to change notification settings - Fork 27.4k
feat(ngMessages): provide support for dynamic message resolution #10676
Conversation
can we expand on this :) |
3e3634d
to
b91eb65
Compare
@@ -87,12 +95,17 @@ | |||
* minlength="5" | |||
* required /> | |||
* | |||
* <div ng-messages="myForm.myEmail.$error" ng-messages-include="my-custom-messages"> | |||
* <!-- any ng-message elements that appear BEFORE the ng-message-incldue will |
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.
typo: ng-message-incldue
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.
fixed.
You could add that being able to apply an array of key names to the Without this requirement I believe that we could have just used interpolation for binding since the attribute type would have only been a string - but I might be wrong. |
}], | ||
|
||
link: function(scope, element, attrs, ngMessagesCtrl) { | ||
ngMessagesCtrl.render = function(collection) { |
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.
Why is this method not in the controller already?
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.
Moved.
Should we move |
@petebacondarwin fixed contains. @petebacondarwin The goal for array-based expressions is noted at the top of the PR. |
@petebacondarwin all code pushed. |
b91eb65
to
8ece832
Compare
Great @matsko - What I meant about the array expressions was that it would be good to include the motivation for the breaking change in the commit message. |
j++; | ||
} | ||
} | ||
require: '^ngMessages', |
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 can be '^^ngMessages'
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.
Moreover it "should" be since it will then provide an error message if the user puts it in the wrong place.
@matsko - if you can address the comments above this looks good to me. A really fascinating bit of work resulting in a much more Angular-ish way of working: not only the ability to use structural elements but also being able to insert |
* | ||
* <!-- or by using element directives --> | ||
* <ng-messages for="expression"> | ||
* <ng-messages-include src="expressionValue1">...</ng-messages-include> |
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.
Shouldn't this be interpolatedValue1 or even {{interpolatedValue}}?
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.
Or, since ng-message
now uses expressions, would it make sense for the include to use them, too? ng-include
already uses expressions. Now there's another include directive, but this one uses interpolation.
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.
Good point, but I think for this PR we'll hold off. The main reason is that ngMessageInclude has to keep track of the old message nodes and then destroy them when the watcher fires. I need some time to figure out a good way to make this work. For now it won't be causing a breaking change.
This looks really useful. A few comments:
Docs:
|
@Narretz - the ngMessages directive works by displaying the first matching message. Its a case of first-in wins. So putting messages earlier overwrites later messages. This should be made clearer in the docs as you say. |
@matsko and @caitp, regarding not having the breaking change of making ng-message expect an expression now. Benefits:
Problems:
|
@petebacondarwin why not just place priority on |
Regarding the naming: I have no problem with two attributes, |
I'm going with |
The reasons why we're going with two attributes are because:
|
+1 - go for it @matsko |
8ece832
to
912b03f
Compare
Now that we agreed on having two attributes, I think we should also put this feature into 1.3. The only breaking change is |
@@ -25,8 +33,10 @@ | |||
* <form name="myForm"> | |||
* <input type="text" ng-model="field" name="myField" required minlength="5" /> | |||
* <div ng-messages="myForm.myField.$error"> | |||
* <div ng-message="required">You did not enter a field</div> | |||
* <div ng-message="minlength">The value entered is too short</div> | |||
* <div ng-message="require">You did not enter a field</div> |
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.
required
Prior to this fix it was impossible to apply a binding to a the ngMessage directive to represent the name of the error. It was also not possible to use ngRepeat or any other structural directive to dynamically update the list of messages. This feature patch ensures that both ngMessages can render expressions and automatically update when any dynamic message data changes. BREAKING CHANGE: The `ngMessagesInclude` attribute is now its own directive and that must be placed as a **child** element within the element with the ngMessages directive. (Keep in mind that the former behaviour of the ngMessageInclude attribute was that all **included** ngMessage template code was placed at the **bottom** of the element containing the ngMessages directive; therefore to make this behave in the same way, place the element containing the ngMessagesInclude directive at the end of the container containing the ngMessages directive). ```html <!-- AngularJS 1.3.x --> <div ng-messages="model.$error" ng-messages-include="remote.html"> <div ng-message="required">Your message is required</div> </div> <!-- AngularJS 1.4.x --> <div ng-messages="model.$error"> <div ng-message="required">Your message is required</div> <div ng-messages-include="remote.html"></div> </div> ``` Closes angular#10036 Closes angular#9338
912b03f
to
5d55976
Compare
Merged as c9a4421 |
I noticed that this is marked with milestone 1.3.14, but no traces of this can be found even in 1.3.15. What is holding this back from being introduced in the 1.3 branch? I cherry-picked this commit on top of the v1.3.x branch and I had no problems applying it, and from my very quick test everything looks to be working as it should. |
(I also needed to apply #11199 as well for my usecase to work, but I had no problem with that one either on my 1.3 branch) |
We had / have double milestones for 1.4 beta and 1.3 releases because we try to release simultaneously. However, only the next minor release receives features, the current stable release only receives bug fixes. |
So no chance of this going in to 1.3 then I take it. We'll see if I'll maintain my own fork, or if we'll just have to live without this feature... In any case, thanks for getting back to me 😃 |
What's the goal here?
-- commit message --
Prior to this fix it was impossible to apply a binding to a the
ngMessage directive to represent the name of the error. It was also
not possible to use ngRepeat or any other structural directive to
dynamically update the list of messages. This fix ensures that both
the ngMessage and ngMessages directives automatically update when
any dynamic message data changes.
BREAKING CHANGE:
The
ngMessagesInclude
attribute is now its own directive and that mustbe placed as a child element within the element with the ngMessages
directive. (Keep in mind that the former behaviour of the
ngMessageInclude attribute was that all included ngMessage template
code was placed at the bottom of the element containing the
ngMessages directive; therefore to make this behave in the same way,
place the element containing the ngMessagesInclude directive at the
end of the container containing the ngMessages directive).
Closes #10036
Closes #9338