-
Notifications
You must be signed in to change notification settings - Fork 27.4k
$watch doesn't work the way it used to work (regression) #9222
Comments
Possibly related to 3f0e642 Can you explain why this matters to you? From the plunker, it looks like the expected behaviour is happening edit I guess it's probably not that commit if this was apparently working in beta 19 |
The built select element is 1 digest behind on rc2 (options wise). The "refresh called" isn't being called immediately after pressing Add more. But it does in beta.19 |
it doesn't look 1 element behind to me, it looks like it's adding a new option every time the button is clicked... |
I am literally watching the DOM update in the debug tools, it looks like it's doing exactly what you're telling it to do. |
Compare both versions, "refresh called" is never called after first press, and subsequently. Starts out with:
After first press, the built element should be:
this does happen on beta.19, but not on rc.2. it's not to watch the SELECT DOM element, the problem lies on the Because the $watch callback is being called 1 digest behind, the items doesn't match. |
well I mean basically you're trying to run your update after ngOptions does its thing, and this is probably not the right way to do it. Maybe we could add some method to the selectControl or something, to notify people when the list is re-rendered. That's probably a better solution than trying to watch the DOM |
@caitp although it worked in beta.19 (and all previous versions). selectController is kinda lacking in features right now, and there's no way to watch over the changed current set of options, I already opened an issue #7417 about this lack of feature. relying on setting a scope variable with the result set of a filter feels hacky |
if pseudo-code: directive('someDirectiveThatDoesSelect', function(){
return {
restrict: 'A',
link: function(scope, el){
scope.$on('$optionsRender', function(event, items){
myjQuerySelectPlugin.addItems(items).refresh();
});
}
}
}); |
@caitp I'd love to submit a PR (I'm in badly need for this) I just don't want to waste time on a PR that wouldn't be accepted, what is better, an array called |
@pocesar trying to catchup on this. Are you saying that if you have |
@lgalfaso nope, I want to get notified when |
@pocesar ok, got it. We do not emit a lot of events (AFAICT, only ng-include and ng-view do), so other options would be best. That said, the PR would not be simple, so I am not sure how open people would be to the change |
An event is probably not what we want to do. But something similar to $viewChangeListeners, why not |
The alternative is making DCCD work for everybody, and that's hard to do :[ |
This is because The relevant commit is most likely 6f7018d Watches should almost never read state from the DOM like you are doing here, it's just a bad practice. I suggest that you create a directive that will register a DOM mutation observer (DMO) on the select element and reexecute the jQuery plugin when DMO fires. |
@IgorMinar MutationEvents were deprecated and Mutation Observer have no good browser support in mobile, why can't angular give a simple way to do this? |
browser support is that bad: http://caniuse.com/#feat=mutationobserver as I said, if we were to give you a hook here, we'd then be asked to give hook in many other places. all these hooks are not needed if you use DMO. alternatively you can observe the model that will cause the dom to be changed (in your case the model that is bound to ng-options) and when it changes, schedule a $timeout that will trigger the jquery plugin. |
I'm not sure there's any reason why we couldn't trigger a DOM event after rendering that people could hook into --- it would be one line of code, and it would have (I think) a pretty minimal perf impact most of the time. But on the other hand, it is what it is |
@IgorMinar this one get's me, directives are all about DOM, and yet, have minor DOM tooling out-of-the-box. I tried scheduling a timeout, and it didn't work (inside @caitp When I asked if would be better to emit an event or creating a listeners array, the prefered way was to use the listeners array. maybe a more general solution of events would be more appropriate now seeing what Igor wrote about |
jQuery events are basically just listener arrays, but you get at them slightly differently. I think in practice you'd still end up wrapping your event listener in a directive. Anyways, I don't know if it's something we can do. I do think it would be a pretty minimal footprint, but if we can't do it, we can't do it |
The dom event is fired already - the DOM mutation event, but because those are known to create perf issues, there were replaced with DMO. I still don't understand why DMO is good for this scenario. It looks like a perfect fit to me. |
Clicking the add more buttom should add items everytime the button is pressed, but it doesn't anymore
http://plnkr.co/edit/n9GS0hECnIu2rrYYbu4d?p=preview
Uncomment script tag of beta.19 and try again (watch the items added to the select element, and the console.log messages)
Beta 19:
rc 2:
The text was updated successfully, but these errors were encountered: