AngularJS - 如何将 html 属性变量值传递给指令?

AngularJS - How to pass html attribute variable value to directive?

... ...

更新

HTML

<my-directive ng-repeat="item in items = ( data | filter: {isExists: true})">
    something
</my-directive>
<my-second-directive counter="{{items.length}}"></my-second-directive>

JS

angular.module('directives')
.directive('myDirective', function () {
    ...
})
.directive('mySecondDirective', function () {
    return {
        restrict: 'EA',
        transclude: false,
        replace: true,
        scope: {
            counter: '@'
        },
        template: '',
        link: function (scope, element, attrs) {
            alert(scope.counter);
        }
    });

对不起,我没有很好地描述我的问题。我的第一个指令应该是 ngRepeated,带有过滤器。但是在我的第二个指令中,我想允许显示一个计数器,当前实例化了多少个第一个指令,因为用户将能够添加和删除实例。所以我想通过第二个指令获得 items.length 的值。但是第二个指令的 link() 方法在 ngRepeat 之前触发,所以计数器的值将是一个空字符串。

提前致谢

更新 2

.directive('cardGroupHeader', function($templateCache){
    return {
        restrict: 'EA',
        transclude: true,
        replace: true,
        require: '^cardGroup',
        scope: {
            cbiscounter: '=?',
            cbcounter: '=?',
            cbisarrow: '@?'
        },
        template: $templateCache.get('card-group-header-tpl.html'),
        link: function(scope, $element, $attrs, cardGroupController) {
            scope.rowId = cardGroupController.getCurrentId();
            console.log(scope.cbcounter);

            scope.toggle = function () {
                cardGroupController.toggle(scope.rowId)
            }
            angular.element(document).ready(function () {
                console.log(scope.cbcounter);
            });

            scope.$watch('scope.cbcounter', function (n, o) {
                if(n && n != o) {
                    console.log(n);
                }
            });
            //scope.cbcounter++;
        }
    };
})

HTML

<card-group-header cbiscounter="true" cbarrow="true" cbcounter="data.length">Waiting for Approval</card-group-header>
    <card-group-row cbCollapsed="false">
        <card ng-repeat="approveItem in data = (approveItems | filter: {isApproved: false, isRejected: false})">

模板

$templateCache.put('card-group-header-tpl.html', '<div class="card-group-header" ng-click="toggle()"><span ng-transclude></span><span class="card-group-counter" ng-if="cbiscounter">{{cbcounter}}</span></div>');

当我把data.length改成2的时候,这个就转好了。如果我使用 data.length,则 scope.cbcounter 始终未定义。如果是 2 我已经在 console.log(scope.cbcounter);

上找回了

counter: '@' 表示您正在接受一个字符串值。如果你想传递一个表达式,你可以使用:

 <my-second-directive counter="{{ items.length }}"></my-second-directive>

或者:

.directive('mySecondDirective', function () {
    return {
        restrict: 'EA',
        transclude: false,
        replace: true,
        scope: {
            counter: '=' // Accept two ways binding
        },
        template: '',
        link: function (scope, element, attrs) {
            alert(scope.counter); 
        }
    });

编辑: 我终于很明白这个问题了!这是因为 直到 link 阶段 之后才对属性进行插值。您有以下两个选择:

第一个选项是将 link 中的 every 包装在 $timeout 内,将其从事件循环中取出并在 DOM 完成操作后执行:

.directive('mySecondDirective', function ($timeout) {
    return {
        restrict: 'EA',
        transclude: false,
        replace: true,
        scope: {
            counter: '=' // Accept two ways binding
        },
        template: '',
        link: function (scope, element, attrs) {
            $timeout(function() {
                alert(scope.counter); 
            });
        }
    });

其次,使用$observe:

attrs.$observe('counter', function(value){
 console.log(value);
});

或按照@jusopi的建议使用$watch

我想这就是你想要的。

Html

<div ng-app="testapp" ng-controller="testctrl">

    <div ng-repeat="item in filtereditems">
        {{item}}
    </div>
    <testdir counter="filtereditems.length" />

</div>

Javascript

angular.module('testapp', [])
.directive('testdir', function(){
    return {
        restrict: 'E',
        scope:{
            counter: '='
        },
        link: function(scope, element, attrs) {
            alert(scope.counter);
        }
    }
})
.controller('testctrl', function($scope, $filter){
    $scope.items = [
        {name: 'A', isExists: true},
        {name: 'B', isExists: false},
        {name: 'C', isExists: true},
        {name: 'D', isExists: false}
    ];
    $scope.filtereditems = $filter('filter')($scope.items, {isExists: true});
})

My jsfiddle is here.

除了@LVarayut 关于作用域绑定表达式的回答之外,警报是 undefined 的原因是因为链接不是 $digest 循环的一部分。因此绑定和数据尚未生效(不要引用我的话,这是我可以用语言表达我在下面的代码中显示的内容的最佳方式)。

相反,您需要使用观察器来触发警报

link: ($scope, elem, attrs)-> 

  #undefined because linking isn't part of the $digest cycle
  #alert $scope.count 

  $scope.$watch 'count', (n, o)->
    if n and n isnt o 
      true
      #alert n

http://plnkr.co/edit/xt95gb3cTXfUEHgpWK1W?p=preview