2016-12-19 5 views
1

私のAngularJs(v1.5.9)アプリケーションでは、リストビューディレクティブを使用しています。リストアイテム内で正確に表現されるべきものは、消費者によって決定され、移譲によって渡されます。AngularJS:属性を使用してディレクティブにデータが渡されない

<list-directive> 
    <list-item> 
    <some more stuff /> 
    <transcluded content /> 
    </list-item> 
</list-directive> 

私は今、この構造体に別のディレクティブを追加しようとしています、トップへの外部からの属性経由で渡すことができるデータを取ります

だから、基本的な構造は次のようになりますそれぞれのリスト項目の入力に応じて処理を行います。

構造がやや複雑で、以下のコードスニペットを最小限に抑えようとしました。ここ

// controller 
 
(function() { 
 
    'use strict'; 
 

 
    function FcDataListCtrl($scope, $q, $element) { 
 
     var that = this; 
 

 
     initVars(); 
 
     init(); 
 

 
     function initVars() { 
 
      that.actionButtons = that.actionButtons || []; 
 
     } 
 

 
     function init() { 
 
     } 
 
    } 
 

 
    angular 
 
     .module('controls.fcDataList.controller', []) 
 
     .controller('fcDataListCtrl', FcDataListCtrl); 
 
})(); 
 

 
(function() { 
 
    'use strict'; 
 

 
    function FcDataList() { 
 
     return { 
 
      restrict: 'E', 
 
      transclude: true, 
 
      template: `<fc-data-list-item ng-repeat="item in ::fcDataList.items" item="::item"> 
 
     <div ng-transclude></div> 
 
    </fc-data-list-item>`, 
 
      scope: { 
 
       items: '=?', 
 
       actionButtons: '=?' 
 
      }, 
 
      controller: 'fcDataListCtrl', 
 
      controllerAs: 'fcDataList', 
 
      bindToController: true 
 
     }; 
 
    } 
 

 
angular 
 
    .module('controls.fcDataList', [ 
 
      'controls.fcDataList.controller', 
 
      'controls.fcDataList.item' 
 
     ]) 
 
     .directive('fcDataList', FcDataList); 
 
})(); 
 

 
(function() { 
 
    'use strict'; 
 

 
    function FcDataListItem() { 
 
     return { 
 
      restrict: 'E', 
 
      replace: true, 
 
      require: '^fcDataList', 
 
      transclude: 'element', 
 
      template: `<div> 
 
          <div ng-transclude></div> 
 
          <fc-item-menu items="fcDataList.actionButtons"></fc-item-menu> 
 
         </div>`, 
 
      scope: { 
 
       item: '=?' 
 
      }, 
 
      link: { 
 
       pre: FcDataListItemLink 
 
      } 
 
     }; 
 

 
     function FcDataListItemLink(scope, elem, attrs, fcDataListCtrl) { 
 
      initVars(); 
 
      init(); 
 

 
      function initVars() { 
 
      } 
 

 
      function init() { 
 
       console.log('FcDataListItem') 
 
       console.dir(fcDataListCtrl.actionButtons); 
 
      } 
 
     } 
 
    } 
 

 
    angular 
 
     .module('controls.fcDataList.item', [ 
 
     'components.fioControlsExtensions.fcDataList.menu' 
 
    ]) 
 
     .directive('fcDataListItem', FcDataListItem); 
 
})(); 
 

 
(function() { 
 
    'use strict'; 
 

 
    function FcItemMenu() { 
 
     return { 
 
      restrict: 'E', 
 
      template: `<div ng-repeat="item in items"> 
 
    <div>{{ item.icon }}</div> 
 
</div>`, 
 
      scope: { 
 
       items: '=?' 
 
      }, 
 
      link: { 
 
       pre: FcItemMenuLink 
 
      } 
 
     }; 
 

 
     function FcItemMenuLink(scope, elem, attrs) { 
 
      scope.open = open; 
 
      initVars(); 
 
      init(); 
 

 
      function initVars() { 
 
       console.log('MenuItem'); 
 
       console.dir(scope.items); 
 
      } 
 

 
      function init() { 
 
      } 
 

 
      function open(event) { 
 
      } 
 
     } 
 
    } 
 

 
    angular 
 
     .module('components.fioControlsExtensions.fcDataList.menu', []) 
 
     .directive('fcItemMenu', FcItemMenu); 
 
})(); 
 

 

 

 
(function() { 
 
    'use strict'; 
 

 
    function AppCtrl() { 
 
     var that = this; 
 

 
     init(); 
 

 
     function init() { 
 
      that.fcDataList = { 
 
       
 
       buttons: [ 
 
        { icon: 'ff-show' } 
 
       ], 
 
       
 
       items: [ 
 
        { firstName: 'Ivan', lastName: 'Petrov', jobPosition: 'Zookeeper' }, 
 
        { firstName: 'Andrei', lastName: 'Müller', jobPosition: 'Pilot' }, 
 
        { firstName: 'Christian', lastName: 'Klein', jobPosition: 'Cook' }, 
 
        { firstName: 'Peter', lastName: 'Stoyanov', jobPosition: 'Fuller' }, 
 
        { firstName: 'Nadine', lastName: 'Wolf', jobPosition: 'Driving Instructor' }, 
 
        { firstName: 'Amya', lastName: 'Krüger', jobPosition: 'Military' } 
 
       ], 
 
     }  
 
    } 
 
} 
 

 
    angular 
 
     .module('controls.example', [ 
 
     'controls.fcDataList' 
 
    ]) 
 
     .controller('AppCtrl', AppCtrl) 
 

 
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script> 
 
<html lang="en" ng-app="controls.example"> 
 
<body ng-controller="AppCtrl as app"> 
 
    <b>Test for data list n stuff</b> 
 
    <fc-data-list items="app.fcDataList.items" 
 
       action-buttons="app.fcDataList.buttons"> 
 
     <div class="row"> 
 
     <span> This is a list item </span> 
 
    </div> 
 
    </fc-data-list> 
 
</body> 
 
</html>

同じ例でCodepen alsowです:https://codepen.io/lyioth/pen/LbqWLz/

は、実際の項目内容のトランスクルーはここでは示されていないことに注意してください(それが問題なく働いています、私はそれをスキップした)。

itemsfc-item-menuの実際の問題は、未定義です。私は、このコンポーネントの上のレベルで問題の配列が実際に空ではないことを示すいくつかのログステートメントを追加しました。

コントローラをrequireに変更して直接actionButtonsプロパティにアクセスすると、動作するようです。しかし、私はむしろそれをしないだろう。

問題は、なぜこれが期待どおりに機能しないのでしょうか?私は何が欠けていますか?

答えて

1

itemsfc-item-menuは、fcDataList.actionButtonsに結合している。つまり、fc-item-menuディレクティブはscope.fcDataList.actionButtonsでそれらを検索します。

fc-data-listディレクティブには、同じタイプのバインディング - fcDataList.itemがあります。これは、bindToControllercontrollerAsを使用したため、スコープフィールドに隔離されたスコープが入れられ、controllerAsscope.fcDataList)で定義された名前が使用されています。戻るfc-item-menu

:あなたはが必要持っているが:^ fcDataListディレクティブで何scope.fcDataListが存在しないため、上記の式は、不定となります。また、それが真であるのは、除外されたスコープが作成されており、scope.fcDataListを持たないためです。それを動作させるための方法はそうのように、コントローラからの値でスコープのプロパティを自分で定義している:

function FcDataListItemLink(scope, elem, attrs, fcDataListCtrl) { 
    scope.buttons = fcDataListCtrl.actionButtons; 
} 

ここで働いてplnkrです:https://codepen.io/anon/pen/GNzELy

は、
関連する問題