You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
Repository navigation
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
the watch would keep track of age property of each item in the users collection and it would fire if a value of this property on any of the user object changes or when a user object is added or removed added to/from the collection.
the newVal and oldVal would be an array of age values with indexes matching the current order of items in the users array.
so during the first digest the watch would fire with these values:
newVal = [33, 22, 11];
oldVal = NaN;
if a new user with age 44 is appended to the array the watch would then fire with:
newVal = [33, 22, 11, 44]
oldVal = [33, 22, 11];
if the only user with age 44 is then updated to 55 the watch would fire with:
notice that the oldVal contents were reordered, to match the new order of elements in the users array as well as newVal array. this is necessary for enabling developers to figure out the actual change (newVal[0] vs oldVal[0]).
implementation notes: it should be possible to reuse hashKeys just like what repeater does to implement this watcher.
Another alternative that I often wish was exposed was a way to reuse the code used to resolve changes to object/arrays for ng-repeat.
It would be cool if that bit of code was refactored as a service available outside ng-repeat. The api could be as simple as $list.$observe(list, listChangeWatcher); where the listChangeWatcher has its only argument being an event object with metadata for the event type, the key that was modified, and other goodies.
Collection watchers are excellent in terms of ease defining rules. I would prefer calling listener one-by-one for each element in list. This approach is used in long-living W3C standard XForms for <bind> element (check http://en.wikibooks.org/wiki/XForms/Bind).
In many features AngularJS is very similar to XForms (bidi-binding, declarative templates, components, watchers) with main difference - there is no so powerful query language for JSON as XPath for XML world. I know that filters give some possibilities. What you suggest is to introduce kind-of querying constructs and I'm full for that.
I would suggest to add other listeners for $watch similar as in XForms binding. Current listener fits for calculate function. It would good to add constraint listener (as validation dimension).
I agree with what I think mstefaniuk is suggesting, in that I'd like the possibility for a collection watch listener to be called on individual collection items when they change.
One possible API I've been thinking about:
$watchItems(collection, detectorFn, listenerFn)
This would create a new type of watcher that iterates over collection, calculates detectorFn(item, collection, index), and if it's not the same as the previous result for that item, calls listenerFn(item, collection, index). The detectorFn should return a simple value or object representing the pieces of the passed item you want to watch, making it sensitive only to the desired fields, and potentially avoiding a deep equals compare for that item
Obviously, it relies on the built-in deep watch, and incurs its overhead. so as-is it's only suitable if running the listener is relatively expensive. If $watchItems was built in, a detector that returned a simple value would be dramatically more efficient than a deep watch, with the added benefit of item-specific listener calls.
I'd seriously love this, and I bet others would too. Thoughts?
Also want to point out that the detectorFn model avoids funky syntax and sub-optimum generic execution plans for expressing which attributes you want to watch, particularly ones at some arbitrary path inside each top-level item.
An enhancement to the current API would be to allow passing such a detector function to $watch as the deepEquality argument. That would provide the potential efficiency improvement, but not the per-matched-item listener calls. An additional boolean argument triggering per-item behavior is also possible, but the implementation I think gets to be pretty different by that point, and a new method seems more appropriate.
Also want to point out that the detectorFn model avoids funky syntax and
sub-optimum generic execution plans for expressing which attributes you
want to watch, particularly ones at some arbitrary path inside each
top-level item.
—
Reply to this email directly or view it on GitHubhttps://github.com//issues/1093#issuecomment-13729651.
@petebacondarwin, while I definitely see value in that proposal, I must be thick, again, because don't I see how they're related to this. This isn't about how anything iterates, only how you can specify that a) change detection could be based on a user provided function, and b) individual collection items are separately tracked, so c) the listener function gets passed the changed item, as well as the whole collection and the index of the item.
However, unless I misunderstand how passing a function as the object to watch works, the external object version from the plunk does everything I need, and my thinking about extra overhead from using $watch was wrong too. Unfortunately, plunkr ate the entire contents of app.js, and I don't see any way to get it back. It's not super complicated, so I will do it, but I can't right now.
That external tool seems like something people could make good use of, so I may just put it up on github.
Activity
ggoodman commentedon Jul 24, 2012
This would really be fantastic. +1
jonricaurte commentedon Nov 27, 2012
I agree. Is there a time frame for when this feature will be added to angular? Thanks.
ggoodman commentedon Dec 6, 2012
Another alternative that I often wish was exposed was a way to reuse the code used to resolve changes to object/arrays for ng-repeat.
It would be cool if that bit of code was refactored as a service available outside ng-repeat. The api could be as simple as
$list.$observe(list, listChangeWatcher);where thelistChangeWatcherhas its only argument being an event object with metadata for the event type, the key that was modified, and other goodies.mstefaniuk commentedon Jan 9, 2013
Collection watchers are excellent in terms of ease defining rules. I would prefer calling listener one-by-one for each element in list. This approach is used in long-living W3C standard XForms for
<bind>element (check http://en.wikibooks.org/wiki/XForms/Bind).In many features AngularJS is very similar to XForms (bidi-binding, declarative templates, components, watchers) with main difference - there is no so powerful query language for JSON as XPath for XML world. I know that filters give some possibilities. What you suggest is to introduce kind-of querying constructs and I'm full for that.
I would suggest to add other listeners for
$watchsimilar as in XForms binding. Current listener fits forcalculatefunction. It would good to addconstraintlistener (as validation dimension).omenking commentedon Jan 21, 2013
I find myself wanting do the following above. I created a helper method in my app since this problem occurs for me frequently.
helper method I wrote (using underscore.js)
helper method output eg.:
just pass it on in
davemerrill commentedon Feb 18, 2013
I agree with what I think mstefaniuk is suggesting, in that I'd like the possibility for a collection watch listener to be called on individual collection items when they change.
One possible API I've been thinking about:
$watchItems(collection, detectorFn, listenerFn)
This would create a new type of watcher that iterates over collection, calculates detectorFn(item, collection, index), and if it's not the same as the previous result for that item, calls listenerFn(item, collection, index). The detectorFn should return a simple value or object representing the pieces of the passed item you want to watch, making it sensitive only to the desired fields, and potentially avoiding a deep equals compare for that item
A proof of concept that creates a deep watch is here: http://plnkr.co/edit/4nPfYtwCd8VfVSyT5OfL?p=preview
Obviously, it relies on the built-in deep watch, and incurs its overhead. so as-is it's only suitable if running the listener is relatively expensive. If $watchItems was built in, a detector that returned a simple value would be dramatically more efficient than a deep watch, with the added benefit of item-specific listener calls.
I'd seriously love this, and I bet others would too. Thoughts?
davemerrill commentedon Feb 18, 2013
Also want to point out that the detectorFn model avoids funky syntax and sub-optimum generic execution plans for expressing which attributes you want to watch, particularly ones at some arbitrary path inside each top-level item.
An enhancement to the current API would be to allow passing such a detector function to $watch as the deepEquality argument. That would provide the potential efficiency improvement, but not the per-matched-item listener calls. An additional boolean argument triggering per-item behavior is also possible, but the implementation I think gets to be pretty different by that point, and a new method seems more appropriate.
petebacondarwin commentedon Feb 18, 2013
Really I think this has to tie in with the proposed changes to ng-repeat:
#1661 (comment)
On 18 February 2013 16:24, Dave Merrill notifications@github.com wrote:
davemerrill commentedon Feb 18, 2013
@petebacondarwin, while I definitely see value in that proposal, I must be thick, again, because don't I see how they're related to this. This isn't about how anything iterates, only how you can specify that a) change detection could be based on a user provided function, and b) individual collection items are separately tracked, so c) the listener function gets passed the changed item, as well as the whole collection and the index of the item.
However, unless I misunderstand how passing a function as the object to watch works, the external object version from the plunk does everything I need, and my thinking about extra overhead from using $watch was wrong too. Unfortunately, plunkr ate the entire contents of app.js, and I don't see any way to get it back. It's not super complicated, so I will do it, but I can't right now.
That external tool seems like something people could make good use of, so I may just put it up on github.
Am I overestimating the value of this strategy?
btford commentedon Aug 24, 2013
As part of our effort to clean out old issues, this issue is being automatically closed since it has been inactivite for over two months.
Please try the newest versions of Angular (
1.0.8and1.2.0-rc.1), and if the issue persists, comment below so we can discuss it.Thanks!