当从函数计算值时,$ watch似乎不起作用

时间:2013-04-03 13:40:35

标签: javascript angularjs angularjs-service

我有一个呈现gridBlocks的转发器。这些块中的每一个都具有“投票好”“投票不好”“无投票”(为了我们的目的)的属性。此属性控制块的CSS类。

用户投票的数据结构是通过userService访问的,它公开了更新投票,执行ajax调用等方法。

我的问题是:

我通过调用voteClass在每个特定块的范围内设置userService属性。我希望在模型更改时观察此属性并相应地更新UI。

然而,这似乎不起作用 - 即使voteClass的值确实发生变化,$watch也不会重新评估,getVoteClass(scope.block.id)也不会被调用。

我尝试使用$apply,但这似乎没有任何改变。

我非常感谢你的意见......

Update1 :我认为即使getVoteClass(scope.block.id)的值发生更改,块范围属性也不会更改。有没有办法强制块范围重新评估其属性?

更新2 - 问题已解决:this question的CaioToOn和Gloopy的帮助下,我意识到错误在于scope属性引用了一个原始字符串。要解决这个问题,您可以观察函数,也可以直接引用对象属性(而不是原始字符串)。


控制器:

    var gridController=['$scope', "userService", function($scope, userService) {

        $http.get(url).success(function(data) {
            $scope.blocks = data;
        });

        $scope.getLookVoteStatus = userService.getLookVoteStatus

    }];

指令:

.directive('gridBlock', function() {
        return {
            link: function(scope, element, attrs) {

                scope.voteClass=getVoteClass(scope.block.id);
                scope.$watch('voteClass',function(newValue, oldValue) {                                                
                    element.addClass(newValue);
                });

             }
        }
    });

1 个答案:

答案 0 :(得分:2)

voteClass在第一次通话后没有变化,虽然getVoteClass的回报是,但不会再次调用。

为了不改变你的榜样,正确的方法是:

function checkForVoteClass() {
  return getVoteClass(scope.block.id);
}

scope.$watch(checkForVoteClass,function(newValue, oldValue) {                                                
  element.addClass(newValue);
})

但请记住,每次在系统的任何地方发生$ apply时,都会重新评估。

那么,当getVoteClass返回不同的值时?在用户互动?如果是,那么最好的方法应该是这样的:

<span ng-click="vote='bad'">Bad</span>
<span ng-click="vote='good'">Good</span>
<span id="thisIsYourElement" 
  ng-class="{bad: 'badCssClass', good: 'goodCssClass', 'undefined': 'noVoteClass'}[vote]"
  >Your content</span>

当然,它非常简化。