Reputation: 7951
Suppose I have a custom directive, named my-directive
, that has the default scope settings (scope: false
, which means it shares the scope of the (parent) controller enclosing the directive), and I have a function my_function
, attached to the controller's scope. I wonder if in the custom directive's link function if I can use scope.$watch
to observe when my_function
executes?
Here's a code for illustration:
<div ng-controller="MyCtrl">
<my-directive></my-directive>
</div>
the controller:
app.controller('MyCtrl', function($scope) {
$scope.my_function = function() {
...
}
});
the custom directive:
app.directive('myDirective', function() {
return {
restrict: 'E',
[scope: false,]
...
link: function(scope, element, attrs) {
// can I scope.$watch my_function here to check when it executes?
}
}
});
Update:
Here's my reason for asking this:
When my_function
(which essentially is a retrieve function through $http.get
) executes, it should update an object, say my_data
. If I try to scope.$watch
my_data
, there may be a situation where my_function
executes and there is no change in my_data
(such as when I edit an entry in my_data
and decides to cancel the update anyway), thus a portion of the code that I want to execute in link function is not executed. So I want to make sure my code in link function executes whenever my_function
executes, whether or not there is a change my_data
.
Upvotes: 3
Views: 634
Reputation: 41440
Here are two ways to solve your problem that I could think of.
You can always increment a counter when invoking my_function
:
// This will reside in your controller
$scope.counter = 0;
$scope.my_function = function () {
// do your logic
$scope.counter++;
};
// This will reside in your directive
$scope.$watch( "counter", function () {
// do something
});
my_data
Assuming my_function
will always override the my_data
variable, you can use the default Angular behavior for $watch
. You don't have to care if your backend has news for you or not, the reference will never be the same.
// in your controller
$scope.my_function = function () {
$http.get(...).then(function ( response ) {
$scope.my_data = response.data;
});
};
// in your directive
$scope.$watch( "my_data", function () {
// do something
});
Obviously, this is the cleaner way to do this, but you may get in trouble if you don't unit test because of one of the following:
my_data
that may conflict with your watcher;I hope I was able to help you! Good luck.
Upvotes: 2
Reputation: 1561
Depending on what you're trying to do, you may not need $watch
at all.
If the function isn't ever going to change, you can just make a dummy wrapper.
link: function(scope, element, attrs) {
var oldFunc = scope.my_function;
scope.my_function = function(sameArgs){
//method_was_called();
if(oldFunc){oldFunc(sameArgs);}
}
}
Then you can do whatever logic you want inside your wrapper function, either before or after you run the 'super' method.
Check also Javascript: Extend a Function
Upvotes: 1