I've written a small JS library for Serial communication in a Chrome app, and it works fine on its own. However, we're running into a problem in integration with Angular: I don't have a way to watch a property of the serial object outside the controller from inside, and I have not been able to find a workaround. Ideally, there's a solution that isn't too computationally expensive, bu at this point, I am not ruling out some way to convert the entire library to a more Angular-friendly format. However, in this situation I'm not sure whether it should go in a service or some other format. Any help would be appreciated.
3 Answers
Just borrowed the idea from here: In AngularJS, how do I add a $watch on the URL hash?
$scope.$watch accepts function as the first argument, so you can do this:
$scope.$watch(function () {
return mylib.myproperty
}, function (value) {
// do stuff
});
UPDATE: As noted in the comments, when mylib.myproperty changes the controller won't know about it until the next digest cicle. Since mylib is not angular-enabled you need to use a plain javascript callback mechanism:
mylib.on_myproperty_change(function(){
$scope.$digest(); // this will cause the $watch to be re-evaluated
});
But since now you already have a mylib.on_myproperty_change you don't really need to $watch anything, so you can delete the watch and just
mylib.on_myproperty_change(function(){
//do the stuff that you did in the the $watch
$scope.$digest();
});
5 Comments
mylib.myproperty, you won't be notified.on_myproperty_change ? I too have an global object I need to track changes for inside a controller and am not able to get $watch to evaluate things when the global obj.property is changed.Create your own custom library as an Angular service:
myAngularApp.service('MyCustomLib', function(){
return myCustomLibInstance;
}]
);
Then you can pass it into a controller and save it to the local scope:
function MyCtrl($scope,MyCustomLib) {
var myCustomLib = MyCustomLib;
And now you have access to your custom library from inside the controller and you can set up a watch, as @tony had suggested in his answer:
$scope.$watch(
function () {
return myCustomLib.property
},
function (newValue, oldValue) {
// do stuff
});
Comments
The method I use to kick off a digest cycle is $timeout(function () {}).
$scope.$digest() will throw an error if there is already an existing digest cycle running.
I have it as
// From my controller
externalService.setOnChangeCallback(function () { $timeout(function () {}) });
// in my service
// on change event
this.onChangeCallBack();
$scope.$watch didn't reliably run for me. Sometimes the watched value was re-evaluated, sometimes it was not.