2016-05-18 7 views
2

私はいくつかの角度指令を持っています。
タイプに応じてng-repeatのアコーディオン・ディレクティブにそれらを含める必要があります。
私はそれを再利用できるようにしたいので、レンダリングされている指示の種類をアコーデオンに知らせたくありません。
そのため、私はアコーディオンの内部でng-switch命令を使用したくありません。 非常に簡単なデモです。実際には、これらのディレクティブは、コンパイルするための独自の属性を持ちます。ng-repeatに異なる角度指令を含める

var testApp = angular.module('testApp', []); 
 
(function() { 
 
    function Element1() { 
 
    return { 
 
     template: '<span>hello</span>', 
 
     restrict: 'E', 
 
     replace: true 
 
    } 
 
    } 
 
    testApp.directive('elementOne', Element1); 
 
}()); 
 

 
(function() { 
 
    function Element2() { 
 
    return { 
 
     template: '<span>world</span>', 
 
     restrict: 'E', 
 
     replace: true 
 
    } 
 
    } 
 
    testApp.directive('elementTwo', Element2); 
 
}()); 
 

 
(function() { 
 
    function Accordion() { 
 
    return { 
 
     template: '<ul><li ng-repeat="element in elements"><button>Toggle</button> Here should be the directive</li></ul>', 
 
     restrict: 'E', 
 
     replace: true, 
 
     controller: function($scope) { 
 
     $scope.elements = [{ 
 
      type: 1 
 
     }, { 
 
      type: 2 
 
     }]; 
 
     } 
 
    } 
 
    } 
 
    testApp.directive('elementAccordion', Accordion); 
 
}());
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app="testApp"> 
 
    <element-accordion></element-accordion> 
 
</div>

ありがとう!

+0

elementAccordionディレクティブに属性として 'elements'を渡す必要がありますか? – hansmaad

+0

@hansmaadはい、例を単純化するために省略しました。 – airnan

答えて

1

私は数週間前に非常によく似たものを作りました。ディレクティブのリストをレンダリングし、配列の要素の型に基づいてディレクティブのタイプを選択したいと思っていました。 ngSwitchを避けようとしました。本当に多くのディレクティブがあり、毎回ngSwitch文を変更せずに新しいディレクティブを追加したいからです。私がしたことの簡略版を見せてください。私はこれがあなた自身のバージョンを構築するのに役立つことを願っています。

最初に、要素diretivesのグローバルディレクトリと、新しいディレクティブを登録するヘルパー関数が必要です。私の場合には、ヘルパー関数もディレクティブを作成しますが、私はそれをシンプルに保つために、これをスキップします:

angular.module("app").provider('elementDirectory', function() {   
    return { 
    elements: [], 
    $get: function() { 
     return { 
     elements: this.elements 
     } 
    } 
    }; 
}); 

function registerElementDirective(type, directiveName) { 
    angular.module("app").config(['elementDirectoryProvider', function (elementDirectoryProvider) { 
    elementDirectoryProvider.elements.push({ 
     type : type, 
     directive : directiveName 
    }); 
    }]); 
} 

、我々はこのようないくつかのディレクティブを作成することができます。

angular.module("app").directive('elementA', function() { 
    return { 
     template: '<span>ElementA</span>', 
    } 
}); 
registerElementDirective('A', 'element-a'); 

最も興味深い部分はelementSwitchと呼ばれる指令です。これは要素の配列を取り、各要素に動的にangular.elementを追加します。したがって、elementDirectoyの各要素のプロトタイプを作成し、変更についてはclone()メソッドを使用します。 (私はこの部分を飛ばすことができると思う、それは最適化だった)。ここで

angular.module('app').directive('elementSwitch', elementSwitch);  
elementSwitch.$inject = ['$compile', 'elementDirectory']; 
function elementSwitch($compile, elementDirectory) { 

    var prototypes = {}; 
    elementDirectory.elements.forEach(function (e) { 
    var directiveElem = angular.element('<' + e.directive + '>'); 
    prototypes[e.type] = directiveElem; 
    }); 

    return { 
    scope: { 
     elements: '=elementSwitch' 
    }, 
    link: function (scope, elem, attr) { 

     var childScopes = []; 
     scope.$watchCollection('elements', function (newValue, oldValue) { 
     childScopes.forEach(function (s) { 
      s.$destroy(); 
     }); 
     childScopes = []; 
     elem.empty(); 

     newValue.forEach(function (element, index) { 
      var childScope = scope.$new(); 
      childScopes.push(childScope); 
      var directiveElem = prototypes[element].clone(); 
      directiveElem.attr('element', '_elements[' + index + ']'); 
      $compile(directiveElem)(childScope); 
      elem.append(directiveElem); 
     }); 
     scope._elements = newValue; 
     }); 
    } 
    } 
} 

完全な例です:https://codepen.io/hansmaad/pen/oLvRmj

それはあなたが望む同じことをしませんが、あなたはあなたの目標を達成できるかのアイデアを取得する必要があります。

+0

非常に興味深いアプローチ。 directiveElem.attr( 'element'、 '_elements [' + index + ']'); はng-repeatがコピーするものです。 配列から対応するデータを持つ「要素」プロパティを公開します。 – airnan

+0

@airnanはい、 'ngRepeat'と同じです。 – hansmaad

関連する問題