3

我在使用 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 替换它,但希望让它只在 angular 中工作。

干杯

4

2 回答 2

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 的回答/评论。

于 2013-02-20T17:32:47.917 回答
2

详细阐述pkozlowski的评论......

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

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

这是你的 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 用于使用适当的值实际更新您的模型。 这是该解决方案的 JSFiddle

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

于 2013-02-20T18:18:42.690 回答