AngularJS 指令需要观察两个属性

Posted

技术标签:

【中文标题】AngularJS 指令需要观察两个属性【英文标题】:AngularJS directive needs to watch two properties 【发布时间】:2012-10-30 23:34:39 【问题描述】:

我正在使用 Angular 制作游戏。每个玩家对象都有一个x 和一个y 属性。每当玩家移动时,我想启动一个计时器,该计时器在精灵表中的几个背景位置循环。

我想我会用一个指令来做到这一点。问题是指令通常只允许你设置一个表达式来观察:

// "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"/>

这种方法的好处是test 指令不必假定作用域具有任何特定属性。当你使用指令时,你告诉它使用什么。

问题是,在我的情况下,如果 x 或 y 发生变化,我需要开始一些事情。我该怎么做?

<div test="player.x, player.y"/>
<div test="player.x" test-two="player.y"/>

有没有你能想到的最好的方法?基本上,如果几个属性中的任何一个发生变化,我想制定一个在计时器上执行某些操作的指令。

【问题讨论】:

请注意,我确实知道您可以将函数传递给 scope.$watch,并返回一些自定义的内容,但这个问题更多的是关于我如何告诉指令在绑定它时在函数中做什么. 【参考方案1】:

我认为最简单、最易读的解决方案是使用两个属性并简单地设置两个手表:

// "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" />

【讨论】:

我也最喜欢这种语法,但如果我想将它用于没有 x 或 y 的东西怎么办?它所做的只是在一个或多个属性更改时激活,但用户可以决定? 您如何看待用户指定要观看的属性? 我想这就是我要问的。在不强制只使用 x 和 y 的情况下,您将如何做您推荐的事情。有任何两个属性?还是单个属性,如果用户想要的话?请参阅我对 eventOn 答案的评论。 现在有watchGroup,你可以把手表挤在一起scope.$watch([attrs.test, attrs.testTwo], doStuff);【参考方案2】:

我会尝试在 $watch 函数中使用一个函数。

这里是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>

【讨论】:

为什么要在 $watch 的第一个参数函数中存储位置? 那么就可以监控定位对象了。 这是使用一只手表监控多个变量的方法。我没有说它更快。但是,我认为它确实为您节省了一块手表。你可能会从中获得一些好处。顺便说一句,AngularJS 的创建者就是这样做的,我看到一个核心成员在某处使用这种方式。 如果您要这样做,那么为什么还要存储变量... scope.$watch(function () return x: attrs.x, y: attrs.y; , ..., 真的);除此之外,您现在还依赖于深度平等。我仍然会使用两个在更改时调用相同函数的手表。 嗯,我认为是一样的。位置是一个局部变量。你只是让它匿名。 “深度平等”是什么意思?【参考方案3】:

有一些解决方法

Watch multiple $scope attributes

https://groups.google.com/forum/?fromgroups=#!topic/angular/yInmKjlrjzI

【讨论】:

&lt;div test="player.x player.y"/&gt; 怎么样?问题是你必须跳过并使用attrs.$observe 而不是scope.$watch。必须根据使用方式更改我使用的功能似乎很奇怪【参考方案4】:
scope.$watch(function () 
  return [attrs.test, attrs.test-two];
, function(value) 
      // do something when it changes
, true);

见this link

您也可以使用 $watchGroup - 请参阅 this link

【讨论】:

以上是关于AngularJS 指令需要观察两个属性的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS数据双向绑定

AngularJS - 无法在链接函数中动态更改指令模板

监控 AngularJS 指令中输入元素上的 $valid

angularjs 指令—— 绑定策略(@=&)

angularjs Directive自定义指令详解

AngularJS学习篇