Как передать значение переменной атрибута html в директиву?

0

......

ОБНОВИТЬ

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

  • 0
    Вы пытались использовать два способа привязки, как показано в моем ответе?
Теги:
angularjs-directive
angularjs-ng-repeat
directive
ng-repeat

3 ответа

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

EDIT: Я, наконец, вполне понимаю проблему! Это из-за атрибутов не интерполируется до этапа ссылки. У вас есть два следующих варианта:

Первый вариант - обматывать каждую ссылку внутри $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.

  • 0
    Хотя это является частью проблемы, другая проблема заключается в том, что он хочет получить длину фильтруемых элементов, {{item.length}} дает исходную длину массива.
  • 0
    Я пробовал это раньше, но поскольку второй метод директивы link () запускается до выполнения ng-repeat, предупреждающее сообщение будет пустым.
Показать ещё 10 комментариев
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});
})

Мой jsfiddle здесь.

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

  • 0
    Я думаю, что link является частью цикла дайджеста. Причиной этого должно быть что-то еще.
  • 0
    Это было то, что я пытался сказать - ссылка Post - последняя функция, которую нужно выполнить. Теперь включение завершено, шаблон связан с областью действия, и представление обновится со значениями, связанными с данными, после следующего цикла дайджеста. - odetocode.com/blogs/scott/archive/2014/05/28/…
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню