【问题标题】:AngularJS custom directive for a ng-indeterminate attribute on checkboxesAngularJS 自定义指令,用于复选框上的 ng-indeterminate 属性
【发布时间】:2014-04-04 07:17:15
【问题描述】:

这是一个处理复选框不确定状态的指令:

.directive('ngIndeterminate', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attributes) {
            attributes.$observe('ngIndeterminate', function(value) {
                $(element).prop('indeterminate', value == "true");
            });
        }
    };
})

然后,以这些数据为例:

$scope.data = [
    {name: 'foo', displayed: 2, total: 4},
    {name: 'bar', displayed: 3, total: 3}
];

你只需要:

<ul ng-repeat="item in data">
    <li>
        <input type="checkbox" ng-indeterminate="{{item.displayed > 0 && item.displayed < item.total}}" ng-checked="item.displayed > 0" />
        {{item.name}} ({{item.displayed}}/{{item.total}})
    </li>
</ul>

有没有什么方法可以编写没有双花括号的 ng-indeterminate 表达式,就像原生的 ng-checked 表达式一样?

ng-indeterminate="item.displayed > 0 && item.displayed < item.total"

我试过了:

.directive('ngIndeterminate', function($compile) {
    return {
        restrict: 'A',
        link: function(scope, element, attributes) {
            attributes.$observe('ngIndeterminate', function(value) {
                $(element).prop('indeterminate', $compile(value)(scope));
            });
        }
    };
})

但我收到以下错误:

Looking up elements via selectors is not supported by jqLite!

Here is a fiddle你可以玩。

【问题讨论】:

标签: javascript angularjs checkbox angularjs-directive


【解决方案1】:

首先,如果你加载 jQuery before angular,你不需要在 jQuery 中包装 element。因此,您将永远不需要在指令中使用 $(element),而是可以直接使用 element,因为 Angular 会自动将 element 包装为 jQuery 对象。

对于您的示例,您实际上甚至不需要 jQuery,因此下面提供的答案根本不依赖 jQuery。

至于你的问题,你可以$watch你的属性值,angular会自动返回编译后的属性值。因此,以下工作如您所料:

.directive('ngIndeterminate', function($compile) {
    return {
        restrict: 'A',
        link: function(scope, element, attributes) {
            scope.$watch(attributes['ngIndeterminate'], function (value) {
                element.prop('indeterminate', !!value);
            });
        }
    };
});

这是一个有效的jsfiddlehttp://jsfiddle.net/d9rG7/5/

【讨论】:

  • 您依赖 jQuery,因为 .prop 是 jQuery 方法,而 element 无论如何都是 jQuery 对象。您可以通过 element[0].indeterminate = !!value 将其剥离,但我不确定这是否是一种改进。
  • @punund .prop 是 jqLit​​e 的一部分,所以不需要 jQuery docs.angularjs.org/api/ng/function/angular.element
  • 顺便说一句,ng-indeterminate 现在是 angular-ui utils 的一部分:angular-ui.github.io/ui-utils
【解决方案2】:

直接使用scope.$evalelement.prop改变属性:

.directive('ngIndeterminate', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attributes) {
            attributes.$observe('ngIndeterminate', function(value) {
                element.prop('indeterminate', scope.$eval(value));
            });
        }
    };
});

FIDDLE


通过使用attributes.$observe,您只能捕获包含插值的属性更改(即{{}})。您应该使用可以观察/观看“表达式”的scope.$watch。所以,我认为@Beyers 的回答更正确。感谢@Chi_Row

【讨论】:

  • $observe 似乎没有注意到这些变化。有什么理由吗? Fiddle example
  • 好的,所以 $observe 没有注意到这些变化,因为 ngInderterminate 属性不包含插值。所以即使对象正在改变 $observe 也不会触发。 $watch 是在这种情况下注意到变化的正确方法。
  • 感谢您的关注。
猜你喜欢
  • 1970-01-01
  • 2023-03-27
  • 2013-03-14
  • 1970-01-01
  • 2019-07-23
  • 1970-01-01
  • 2019-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多