I'm making a game in Angular. Each player object has an x
and a y
property. Whenever the player moves, I want to start a timer that cycles through a couple background positions in the sprite sheet.
I thought I would do this with a directive. The problem is that directives normally only let you set one expression to watch:
// "test" directive
module.directive("test", function() {
return function(scope, element, attrs) {
scope.$watch(attrs.test, function(value) {
// do something when it changes
})
}
})
// my template
<div test="name"/>
The nice thing about this approach, is the test
directive doesn't have to assume the scope has any particular property. You're telling it what to use when you use the directive.
The problem is that in my case I need to kick something off if either x OR y changes. How can I do this?
<div test="player.x, player.y"/>
<div test="player.x" test-two="player.y"/>
Is there a best way to do this that you can think of? Basically I want to make a directive that does something on a timer if any of several properties change.
The easiest and most readable solution in my opinion is to use two attributes and simply set up two watches:
// "test" directive
module.directive("test", function() {
return function(scope, element, attrs) {
var doStuff = function() {
console.log(attrs.test);
console.log(attrs.testTwo);
}
scope.$watch(attrs.test, doStuff);
scope.$watch(attrs.testTwo, doStuff);
}
})
// my template
<div test test="player1.x" test-two="player1.y" />
I would try to use a function in the $watch function.
Here is the plunker
var app = angular.module('plunker', [])
.directive('myDir',function(){
return {
restrict:'E',
template:'<span>X:{{x}}, Y:{{y}}</span>',
link:function(scope, elm, attrs){
scope.$watch(function (){
var location = {};
location.x = attrs.x;
location.y = attrs.y;
return location;
}, function (newVal,oldVal,scope){
console.log('change !');
scope.x = newVal.x;
scope.y = newVal.y;
}, true);
}
};
});
app.controller('MainCtrl', function($scope) {
});
<div>X: <input type='text' ng-model='x'/></div>
<div>Y: <input type='text' ng-model='y'/></div>
<my-dir x='{{x}}' y='{{y}}'></my-dir>
There is some work arounds for this
Watch multiple $scope attributes
https://groups.google.com/forum/?fromgroups=#!topic/angular/yInmKjlrjzI
scope.$watch(function () {
return [attrs.test, attrs.test-two];
}, function(value) {
// do something when it changes
}, true);
see this link
you can also use $watchGroup - see this link
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