It appears that if you use a jQuery slider to edit a hidden input field on slide, +AngularJS won't pick up that change event, not even if I explicitly call $(element).change() on it. However, the regular change still fires, jQuery does a good job.

So if I have an element with the following attributes: ng-change="console.log('something1')" onchange="console.log('something2')", only the first one fires when I change the slider value.

Anyone experienced this? Angular bug?
1
J.Joe Douglas's profile photoChris Johnson's profile photoBruno Škvorc's profile photo
12 comments
 
You're causing changes outside of the normal update (this probably isn't the correct term) cycle of angular. You want to call $apply() to get angular to check for changes to the $scope and update the view appropriately.
 
But I have no access to scope. Scope is undefined, it says.
 
http://docs.angularjs.org/api/angular.element

In the notes section, observe the scope() method.  I believe you could do something like angular.element($('ng-controller="yourControllerNameHere"')).scope().$apply();  Of course I'm typing this into a textbox and don't have access to your code so some fiddling around may be required but hopefully this will put you on the right path :)
 
$apply() is one of those methods that you should probably rarely use (if ever).  It involves a bit more knowledge of the implementation of Angular than you may want your application to have.  Another way to say that is that using $apply() leads to dependencies that are difficult to unit test.

See: http://jimhoskins.com/2012/12/17/angularjs-and-apply.html for a good introduction to $apply() and when you may want to use it.
 
+J.Joe Douglas thanks for the assist. This seems to be vaguely on the right track, but produces some oddities. For example, calling $apply does nothing, but it works - no error is thrown. If I try to access [...].scope().my_model, it returns undefined - as if it gave back the wrong scope.

The model I need to react to the change is in a directive, so it's well possible that it retrieved the scope of the controller containing the directive, and not the scope of the directive itself.

I would never have thought this would be so difficult. I would have been done days ago with jQuery, testability be damned.
 
You're taking two different UI paradigms and trying to make them work together.  jQuery = imperative, Angular = declarative.  There's bound to be problems mapping between the two.
 
I suppose, yes. What do you recommend instead? How do I achieve the same UX transformation jQuery UI allows, with Angular and without sacrificing customizability?
 
There are several UI that do not behave well in Angularjs. The solution is to create a directive that handles the UI.  You can then access the element and its events and update your scope in the link function. 
 
But re-creating the styleable jQuery UI slider and making it cross-browser compatible like they did is a fool's errand, why reinvent the wheel? Or is there a way to init the slider from within the directive itself which would handle this issue?
Add a comment...