2016-07-06 19 views
1

"データグリッド"機能をHTMLテーブルに追加するために使用されているコンポーネントを作成しました。ヘッダーはクリック可能で、その列のデータのソート(昇順/降順)が可能です。これまでのところ、同じページに2つのコンポーネントのインスタンスがない限りうまくいきました。ある表のヘッダーをクリックすると、両方の表に影響します。イベントをAngular 1.5で分離するコンポーネントインスタンス

コンポーネントのイベントを分離してそのインスタンスに影響を与える方法がありますか?

コンポーネント:

angular.module('app') 
     .component('datagrid', { 
      templateUrl:'components/datagrids/datagrids.component.html', 
      controller:DatagridController, 
     }) 

コントローラ(進行中の作業、私はそれが現時点では混乱のビットです知っている!):

function DatagridController($filter, datagridService){ 
    var ctrl = this; 
    ctrl.today = new Date(); 
    ctrl.sortBy = null; 
    ctrl.fields = []; 
    ctrl.data = []; 
    ctrl.update = function(){ 
     var service = datagridService; 
     console.log(datagridService); 
     var updatedFields = []; 
     console.log(datagridService.fields); 
     for(var i = 0; i < datagridService.fields.length; i++){ 
      var fieldName = datagridService.fields[i]; 
      var fieldDirection = (ctrl.fields.length === 0) ? 'ascending' : ctrl.fields[i].direction; 
      updatedFields.push({name:fieldName, direction:fieldDirection}); 
     } 
     ctrl.fields = updatedFields; 
     console.log(ctrl.fields) 
     if (ctrl.sortBy == null){ ctrl.sortBy = $filter('toCamelCase')(ctrl.fields[0].name); } 
     ctrl.data = datagridService.data.sort(ctrl.sortData(ctrl.sortBy)); 
     ctrl.today = new Date(); 
    }; 
    ctrl.sortData = function(field, reverse, primer){ 
     console.log(field + ' | ' + reverse) 
     var key = primer ? 
      function(x) {return primer(x[field])} : 
      function(x) {return x[field]}; 
     reverse = !reverse ? 1 : -1; 
     ctrl.sortBy = field; 
     return function (a, b) { 
      return a = key(a), b = key(b), reverse * ((a > b) - (b > a)); 
     } 
    }; 
    ctrl.toggleSortDirection = function(index){ 
     console.log(index); 
     var field = ctrl.fields[index]; 
     console.log(field); 
     var fieldName = field.name; 
     console.log(fieldName); 
     var direction = ctrl.fields[index].direction; 
     console.log(direction); 
     var reverse = (direction == 'ascending') ? true : false; 
     console.log(reverse); 
     var direction = (direction === 'ascending') ? 'descending' : 'ascending'; 
     console.log(direction); 
     for(var i = 0; i < ctrl.fields.length; i++){ 
      ctrl.fields[i].direction = 'ascending'; 
     } 
     ctrl.fields[index].direction = direction; 
     ctrl.data.sort(ctrl.sortData($filter('toCamelCase')(fieldName), reverse)); 
    }; 
    ctrl.validDatetime = function(dt){ 
     //this should probably be a service 
     console.log(dt); 
     var rx = /([0-9]{4})\-([0-9]{2})\-([0-9]{2})/; 
     if(dt.match(rx)){ console.log(dt); } 
     return (dt.match(rx)) ? true : false; 
    }; 
    ctrl.$onInit = ctrl.update(); 
} 
DatagridController.$inject = ['$filter', 'datagridService']; 

テンプレート:

<table ng-if="$ctrl.data.length > 0" class="datagrid"> 
    <caption ng-if="$ctrl.caption">{{ $ctrl.caption }}</caption> 
    <colgroup ng-if="$ctrl.colgroup.length > 0"> 
     <col ng-repeat="col in $ctrl.colgroup"> 
    </colgroup> 
    <thead ng-if="$ctrl.hasHeader = true"> 
     <tr>  
      <th ng-repeat="field in $ctrl.fields" ng-click="$ctrl.toggleSortDirection($index)" data-sortable="true">{{ field.name }}<div ng-class="field.direction"></div></th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr ng-repeat="record in $ctrl.data"> 
      <td ng-repeat="field in $ctrl.fields"> 
       <span ng-if="!$ctrl.validDatetime(record[(field.name|toCamelCase)])"><a>{{ record[(field.name|toCamelCase)] }}</a></span> 
       <span ng-if="$ctrl.validDatetime(record[(field.name|toCamelCase)])"><a>{{ record[(field.name|toCamelCase)] | date: 'dd-MMM-yyyy' }}</a></span> 
      </td> 
     </tr> 
    </tbody> 
    <tfoot ng-if="$ctrl.hasFooter = true"> 
     <td colspan="{{ $ctrl.fields.length }}">Last Updated: {{ $ctrl.today | date: 'dd-MMM-yyyy' }}</td> 
    </tfoot> 
</table> 

コンポーネントタグ:

<datagrid></datagrid> 
+0

代わりctrl.dataを使うのか?私は複数のDOMオブジェクトに同じコントローラが割り当てられている同様のアプリケーションを持っています。デフォルトでは、それらはすべてそのコントローラの独自のインスタンスを持ちます。 – MadPhysicist

+0

私はAngular Componentsで見つかったドキュメントを読んできましたが、私が読んだことからコントローラはそのコンポーネントに割り当てられています。この方法でテンプレートにコントローラを接続する例は見ていません。コンポーネントは、タグ – Eric

答えて

1

コンポーネントはデフォルトで隔離されています。つまり、インスタンスごとに独自の$ctrが存在します。

データはサービスを通じて共有されるということです。たとえば、最初のインスタンスでdatagridService.data.sortを実行します。>サービス内のデータを変更する=>コンポーネントのすべてのインスタンスに反映されます(アクセスしようとしているメモリにdataオブジェクトが1つあります)。

1つの問題は、すべてのコンポーネントインスタンスのデータのコピーを作成することです。

ctrl.data = Object.assign([], datagridService.data); 

いけないdatagridService.dataに直接任意の操作を行いますが、どのようにあなたのテンプレートでコントローラを割り当てる

+1

を介してページに挿入されます。ヒープのおかげで、oKonyk。私はそれを見ているとは思わなかったので、私はとても包まれました! – Eric

+0

お力になれて、嬉しいです! – oKonyk

関連する問題