指令更改相关范围值后,ng-show不更新

时间:2013-02-20 13:37:27

标签: javascript angularjs

我遇到了ng-show方法的问题,我将方法设置如下:

我检查用户名字符串的长度,但即使它报告了正确的长度,ng-show方法也不会隐藏/显示我的额外文本,直到之后的按键。如何让它更新密钥上的用户名帮助文本的可见性

如果你看看JS小提琴http://jsfiddle.net/FkAkg/8/

怎么样?
           accountApp.directive("stripCharacters", ['$filter', '$http', function($filter, $http) {
            return {
                restrict: 'C',
                link: function(scope, element) {
                    element.bind("keyup", function() {
                        if(scope.account.username !== undefined) {
                            element.val($filter('stripCharacters')(scope.account.username));
                            if(scope.account.username.length > 2) {
                                scope.toggleShowUsername(true); 
                                scope.usernameMessage = scope.account.usernameAvailable;
                            } else {
                                scope.toggleShowUsername(false);
                            }
                        }
                    });
                }
            }
        }]);

我已经让它在同一个元素上用jQuery hide / show替换它,但是希望它只能在角度上工作。

干杯

2 个答案:

答案 0 :(得分:2)

keyup处理程序在Angular的“外部”运行,因此使用scope.$apply()使Angular注意到您更改了showUsername

...
if(scope.account.username.length > 2) {
   scope.toggleShowUsername(true); 
   scope.usernameMessage = scope.account.usernameAvailable;
} else {
   scope.toggleShowUsername(false);
}
scope.$apply();

以上回答了您的问题,但我建议@ pkozlowski.opensource的回答/评论。

答案 1 :(得分:2)

阐述pkozlowski的评论......

我也认为你试图在一个地方做太多。该指令的(单一)责任是什么?根据名称它是“剥离字符”......但是如果你看看你在里面做了什么,你就是剥离字符,调用方法并更新指令所在元素之外的元素的显示逻辑。 / p>

我建议您简化指令,并将其他内容移到$ watch:

Here's a fork of your JSFiddle

相关代码:

在你的控制器中我添加了以下内容......

$scope.$watch('account.username', function (value) {
   if (value.length > 2) {
      $scope.toggleShowUsername(true);
      $scope.usernameMessage = $scope.account.usernameAvailable;
   } else {
      $scope.toggleShowUsername(false);
   }
});

然后你的指令:

accountApp.directive("stripCharacters", ['$filter', function ($filter) {
   return {
      restrict: 'C',
      require: 'ngModel',
      link: function (scope, element, attrs, ngModel) {
            ngModel.$parsers.unshift(function (value) {
               var stripped = $filter('stripCharacters')(value);
               element.val(stripped);
               return stripped;
            });
      }
   }
}]);

要明确的是,Mark Rajcok的答案也适用于此,对你来说可能更合适......但它缺少一件:$ setViewValue。如果是这样,您只需将上面指令的链接功能更改为:

link: function (scope, element, attrs, ngModel) {
    element.bind('keyup', function () {
       var value = element.val();
       var stripped = $filter('stripCharacters')(value);
       element.val(stripped);
       ngModel.$setViewValue(stripped);
       scope.$apply();
    });
}

其中$ setViewValue用于使用适当的值实际更新模型。 Here's a JSFiddle of that solution;

我希望所有这些都有帮助。