2013-04-04 35 views
1

我很确定我做错了什么,因为我的角度很少有经验。 也许答案已经在stackoverflow的某个地方了,我不是在问(正确搜索)正确的问题。

我有这个非常简单的指令。这只是一个有四个状态的跨度,我希望在跨度上的每次点击都进行更改。每次点击都会向前推进状态,然后循环回去。每个州都有不同的CSS类。 每次更改指令的值时,我都希望父级模型中的值发生更改(因此隔离范围声明中的“=”,对吧?)。

我把一个值放在改变类的值上,以便每次值改变时都更新css类。

现在,问题是,当我点击时,手表被触发newValue,但手表再次触发newValue等于点击前的值。

我认为这是与脏检查和父控制器模型的连接有关的事情,但是,这样做的正确方法是什么?并且/或者获得相同结果的方式更好,更有说服力?

这里的指令:

.directive('square', function() { 
    return { 
     restrict: 'E', 
     transclude: true, 
     scope : { 
      value : '=', 
     }, 
     link: function(scope, elm, attrs, ctrl) { 

      scope.valueToClass = function(value) { 
       var result = 'square-empty'; 
        if (value == '1') { 
         result = 'square-temp'; 
        } else if (value == '2') { 
         result = 'square-confirmed'; 
        } else if (value == '3') { 
         result = 'square-critical'; 
        } 
       return 'block-'+result; 
      } 

      scope.$watch('value', function(newValue, oldValue) { 
       scope.blockClass = scope.valueToClass(newValue) 

      }, true); 

     }, 
     controller: function($scope, $element, $attrs) { 
      $scope.changeValue = function() { 
       $scope.value = ($scope.value+1) % 4; 
      } 
     }, 
     template : '<span class="{{blockClass}}" ng-click="changeValue();">'+'</span>', 
     replace: true 
    }; 
}); 

这里>>the fiddle<<

+0

请分享jsfiddle – 2013-04-04 10:07:23

+0

同时,我试图让它在小提琴中工作。只是想知道是否有什么明显的错误。 – Duralumin 2013-04-04 10:10:40

回答

3

这是因为你看在你的$ scope.block阵列的原始值(整数)的变化。

在控制器

$scope.block = [{value: 3}, {value: 2}, {value: 1}, {value: 0}]; 

试试这个,然后在视图:

<square ng-repeat="squareValue in block" value="squareValue.value"></square> 

(ENGLSH不是我的第一语言,简短的回答很抱歉)

+0

这里是我的版本:http://jsfiddle.net/TYdzJ/ – 2013-04-04 11:06:23

3

你不应该使用原始值观看更改,因为由于JavaScript子范围中的原型继承覆盖了父范围值。敬请参阅非常好的文章,其中解释了所有原因。 https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-Prototypal-Inheritance

+0

谢谢你,Ajay和@ ardentum-c,两个答案都解决了我的问题。我很不确定选择哪一个被接受,最后是因为小提琴而选择了ardentum,因为他更需要声望;) – Duralumin 2013-04-04 12:29:07

0

另一个答案可能帮助别人就是你需要检查的newval已经改变,的newval将始终传入,所以你需要检查它是不一样的,即:

$scope.$watch('someProperty', function(newVal, oldVal) { 
    if (newVal !== oldVal) { 
     // do something 
    } 
}); 

我发现这解决了$ watch监听器过早启动的问题,无论scope属性是否是原始的,即我的属性是一个整数$ scope.menuId。