I'm implementing a simple spinner control in AngularJS and I want to react both on user input and changes from +/- buttons. Here is my HTML:
<input type='button' ng-click="MyProperty = MyProperty - 1" value="-">
<input type='text' ng-model="MyProperty" ng-change="log('changed from ngChange')">
<input type='button' ng-click="MyProperty = MyProperty + 1" value="+">
But this will track only 'user-changes' far as ngChange
supports only user-interaction updates as per documentaiton
So now I'm looking at $scope.$watch
as Frederik recommends:
$scope.$watch('MyProperty', function() {
$scope.log('changed from $watch');
});
See plunker demo
But this doesn't seem right enogh.
MyTestProperty
to find this binding.$scope.log
in a separate Model you have to either inject $scope
or to do the binding in controller. And as far as I understand both ways are not considered to be the best practicies.Some people think that $watch
is a bad thing in general for a number of other reasons. But the solution advised there (which would be calling log
in ngClick directly) doesn't make too much diference to me. Basicly you have to manually track all the changes and if new actor comes you have to copy your logic there.
So the questions would be: is there a way that allows you to automaticly keep track of model updates without $watch? And how bad is the idea to implement your own derective for this if there is now such way?
There are couple of ways to do this, but the most elegant way is requiring the ngModel of the input and then use it to view / manipulate the value.
Here is your updated Plunker.
.directive('outputIt', function() {
return {
restrict: 'A',
scope: {
outputIt: '&'
},
require: '?ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$parsers.push(function(val) {
//console.log("the model was changed by input")
scope.outputIt()(val);
});
ngModelCtrl.$formatters.push(function(viewValue) {
//console.log("the model was changed from outside.");
scope.outputIt()(viewValue);
return viewValue;
});
}
}
})
To find out more about it, here is a very cool article about it:
Atricle
Good luck!
Have you looked into the ES5 way? It's essentially javascript's native $watch functionality. The difference is you keep the set/get functions are encapsulated with the property, whereas a $watch can be applied externally anywhere.
var MyCtrl = function(){
this._selectedItem = null;
};
Object.defineProperty(MyCtrl.prototype, "selectedItem", {
get: function () {
return this._selectedItem;
},
set: function (newValue) {
this._selectedItem = newValue;
//Call method on update
this.onSelectedItemChange(this._selectedItem);
},
enumerable: true,
configurable: true
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With