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

时间:2015-10-02 02:21:18

标签: angularjs angularjs-directive angularjs-ng-repeat ng-repeat directive

... ...

更新

HTML

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);
        }
    });

JS

.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++;
        }
    };
})

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

提前致谢

更新2

<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})">

HTML

$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>');

TEMPLATE

data.length

当我将2更改为data.length时,转移得很好。如果我使用scope.cbcounter 2始终未定义。如果是console.log(scope.cbcounter);,我已将其恢复到{{1}}

3 个答案:

答案 0 :(得分:1)

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); 
        }
    });

修改 我终于明白了这个问题!这是因为属性直到链接阶段之后才被插值。您有以下两个选项:

第一个选项是将$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);
});

或使用$watch作为@jusopi建议。

答案 1 :(得分:1)

我认为这就是你想要的。

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.

答案 2 :(得分:1)

除@ 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