0

... ...AngularJS - 如何將html屬性變量值傳遞給指令?

UPDATE

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之前被觸發,所以計數器的值將是一個空字符串。

預先感謝

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

TEMPLATE

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

WHE n我將data.length更改爲2,這個轉移良好。如果我使用data.length,則scope.cbcounter總是未定義。在2的情況下,我找回了console.log(scope.cbcounter);

+0

你嘗試用兩種方法結合,如圖我的答案? – lvarayut

回答

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建議。

+0

雖然這是問題的一部分,但另一個問題是他想要獲得被過濾項目的長度,「{{item.length}}」給出了原始數組的長度。 – jusopi

+0

我以前試過,但因爲第二個指令link()方法在ng-repeat之前被觸發,所以警報消息將是空的。 – MontyX

+0

@ jusopi你是不對的。過濾的是這種情況下的項目,數據是原始數據。 – MontyX

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.

1

除了@ LVarayut的有關範圍的綁定表達式的答案,該警報是undefined的原因是因爲連接不的一部分週期爲$摘要週期。所以綁定和數據還沒有生效(不要引用我的意思,這是我可以用語言表達我在下面的代碼中展示的最佳方式)。

相反,你需要使用一個觀察者來觸發警報

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'是摘要循環的一部分,背後的原因應該是別的。 – lvarayut

+0

這就是我想說的 - * Post鏈接是最後一個要執行的函數。 ,模板鏈接到範圍,並且視圖將在下一個摘要循環後更新數據綁定值。* - http://odetocode.com/blogs/scott/archive/2014/05/28/compile-pre- and-post-linking-in-angularjs.aspx – jusopi

+0

我敢打賭'ng-repeat'是罪魁禍首,這是一個*邊緣案例*,即過濾後的d在DOM呈現之後,會創建ata集合。注意$ watch。他可能也可以通過'$ timeout'來做到這一點,雖然不會因爲過濾的數據更改而更新。 – jusopi

相關問題