In my multi-user AngularJS app, I have a model object on my scope. This model can be manipulated by both user input and server updates.
I have a $watch observer to track the model and update the UI. Is it possible to determine the source/reason of my model update from within my $watch function? Without that check, I have problems with feedback loops (e.g. UI→Server→UI).
UPDATE: some code
Controller:
$scope.elementProperties = { left: 0 };
$scope.$watch('elementProperties.left', function(newVal, oldVal) { changeSelectedElementProperty('left', newVal, oldVal); } );
Directive:
angular.module('myapp.ui-editor').directive('myappPropertiesPanel', function () {
return {
templateUrl: 'views/ui-editor/myappPropertiesPanel.html',
restrict: 'A',
scope: { elementProperties: '=' },
link: function postLink (scope, element, attrs) {
scope.$watch('elementProperties.left', function(newVal, oldVal) { console.log('PropertiesPanel change left', newVal, oldVal); } );
}
};
});
What is the angular JS watch function? The angular JS $watch function is used to watch the scope object. The $watch keep an eye on the variable and as the value of the variable changes the angular JS $what runs a function. This function takes two arguments one is the new value and another parameter is the old value.
AngularJS ng-repeat Directive The ng-repeat directive repeats a set of HTML, a given number of times. The set of HTML will be repeated once per item in a collection. The collection must be an array or an object. Note: Each instance of the repetition is given its own scope, which consist of the current item.
To change path URL with AngularJS, $location. path() is passed the new URL as a parameter, and the page is automatically reloaded. This means that if you ever make a change to the URL in an Angular application, then the partial and controller will be reloaded automatically.
One way of achieving this is by using events instead of $watch
See working plunker here
In my plunker, I've put in a $interval
that will simulate a web service call by changing the value every few seconds.
Here is what you can do.
In the then
handler of your http call, before you set the new value retrieved from the web service to the model, publish an event with a payload containing the old value and the new value like below:
$http.get('url goes here')
.then(function (response) {
scope.$broadcast('UPDATE_FROM_SERVER',
{oldValue: scope.elementProperties.left, newValue: response.data.left});
scope.elementProperties.left = response.data.left;
};
Then, in your form control, where the user will change the value, attach an ng-click
like below:
ng-change="userChangeHandler(elementProperties.left, '{{elementProperties.left}}')
Notice the quotes around '{{elementProperties.left}}'
. This will ensure that the change handler function will get the old value of the property.
Now, you can listen to these change events like below:
$scope.$on('UPDATE_FROM_SERVER', function (event, changes) {
// This code will be invoked when the data is changed by the server
$scope.messages.push('Data changed by Server from ' + changes.oldValue + ' to ' + changes.newValue);
});
$scope.$on('UPDATE_FROM_USER', function (event, changes) {
// This code will be invoked when the data is changed by the user
$scope.messages.push('Data changed by User from ' + changes.oldValue + ' to ' + changes.newValue);
});
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