-
Notifications
You must be signed in to change notification settings - Fork 27.4k
Collection attribute watches: $watch('object@attribute') #1093
Comments
This would really be fantastic. +1 |
I agree. Is there a time frame for when this feature will be added to angular? Thanks. |
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 |
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 |
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) AppHelper =
collection_exp:(scope,name,attr)=>
eval "collection = scope.#{name}"
count = collection.length
exp = []
_.each collection, (e,i)=>
exp.push "#{name}[#{i}].#{attr}"
exp.join ' + '
window.AppHelper = AppHelper helper method output eg.:
just pass it on in exp = AppHelper.collection_exp @$scope, 'calendar.tasks', 'data'
@$scope.$watch exp, =>
# make it happen |
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: 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? |
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. |
Really I think this has to tie in with the proposed changes to ng-repeat: On 18 February 2013 16:24, Dave Merrill notifications@github.com wrote:
|
@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? |
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 ( Thanks! |
Often it is useful to be notified if
Given model:
and watch:
the watch would keep track of
age
property of each item in theusers
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:
if a new user with age 44 is appended to the array the watch would then fire with:
if the only user with age 44 is then updated to 55 the watch would fire with:
if the users array is sorted and items in the array are moved around but user is added/removed/deactivated then no watch fires.
if the first user is then updated to age 99 (after sorting) and this user was previously the last user in the array then the watch should fire with:
notice that the oldVal contents were reordered, to match the new order of elements in the
users
array as well asnewVal
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.
The text was updated successfully, but these errors were encountered: