2016-07-26 2 views
8

私はオブジェクトの配列を持っています。これらの各オブジェクトには、文字列値を持つ「コンポーネント」プロパティがあります。今度は、リストをループして、参照されている各コンポーネントをレンダリングします。ループされたオブジェクトのその他のプロパティは、コンポーネントのパラメータを提供することになっています(以下の例には含まれていません)。AngularJSに手続き的にコンポーネントを含める

私のソリューションこれまでの作品が、スイッチケースで許可される要素を記述し、不要なラッパー要素を作成が必要です。

angular.module('switchExample', []) 
 
     .controller('ExampleController', ['$scope', 
 
     function($scope) { 
 
      $scope.items = [{ 
 
      component: "alpha" 
 
      }, { 
 
      component: "beta" 
 
      }, { 
 
      component: "alpha" 
 
      }]; 
 
     } 
 
     ]) 
 
     .component('alpha', { 
 
     template: "this is component alpha", 
 
     }) 
 
     .component('beta', { 
 
     template: "this is component beta" 
 
     })
<!doctype html> 
 
<html lang="en"> 
 

 
<head> 
 
    <meta charset="UTF-8"> 
 
    <title>Example</title> 
 
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script> 
 
</head> 
 

 
<body ng-app="switchExample"> 
 
    <div ng-controller="ExampleController"> 
 
    <div ng-repeat="s in items" ng-switch="s.component"> 
 
     <alpha ng-switch-when="alpha"></alpha> 
 
     <beta ng-switch-when="beta"></beta> 
 
    </div> 
 
    </div> 
 
</body> 
 

 
</html>

は、手続きの構成要素を含んする方法はあります文字列比較と明示的な呼び出しの往復なしで?このような

何か、多分?:

<div ng-repeat="s in items"> 
    <component ng-component="s.component"></component> 
</div> 

またはより良い:

<div ng-repeat="s in items" ng-component="s.component"></div> 

または代わり:

<div ng-component="s.component for s in items"></div> 
+0

どういうところですか? – svarog

+0

申し訳ありませんが明確ではありません。最後に質問が追加されました。 –

+0

これをシームレスに行うための 'ng-component 'はありません。これは、その内容を再コンパイルする指令として終わることになります(パフォーマンスペナルティはもちろんです)。ダイナミックディレクティブのようなものを検索することで、このアプローチに慣れることができます。 – estus

答えて

2

GitHub:https://github.com/hubertgrzeskowiak/angular-component-directiveですべてのドキュメントとダウンロード。

私の答えに基づいて、私はこれをややクリーンで多目的に再実装しました。デモ:http://plnkr.co/edit/uDxIUulQPx4C3s11b5cG?p=preview

使用(フルドキュメントFOREのGitHubを参照してください):

<component name="expr" args="expr" replace="expt"></component> 

...ここで、 "名前" という表現は、コンポーネント名(文字列)に評価される必要があり、 "引数"(オプション)必須オブジェクトに評価し、 "replace"(オプション)はブール値に評価する必要があります。 argsは新しいコンポーネントの属性に展開されるので、そのオブジェクトのすべての値は式です。 "replace"がtrueの場合、コンポーネントはそれ自身を置き換えます。

0

はのようなものはありませんng-これをシームレスに行うコンポーネントです。これは、その内容を再コンパイルする指令として終わることになります(パフォーマンスペナルティはもちろんです)。あなたは「ダイナミックディレクティブ」

estus

おかげで、estusのようなものを検索することにより、アプローチに慣れることができます!

私はそれを正確に行いました!あなたは以下を参照することができますcomponent

カスタムディレクティブは、渡されたnameパラメータに基づいてコンポーネントを作成して、任意のargsをとります。

例入力:

<component name="'alpha'"></component> 

出力:引数と

<component name="'alpha'"> 
    <alpha> 
     whatever alpha component decides to render in its template 
    </alpha> 
</component> 

<component name="'alpha'" args="{foo:'bar', num:42, o:{a:1}}"></component> 

出力:

<component name="'alpha'" args="{foo:'bar', num:42, o:{a:1}}"> 
    <alpha foo="'bar'" num="42" o="{a:1}"> 
     whatever alpha component decides to render in its template with the given args 
    </alpha> 
</component> 

angular.module('switchExample', []) 
 

 
.directive('component', ['$compile', 
 
    function($compile) { 
 
    return { 
 
     restrict: 'AEM', 
 
     scope: { 
 
     name: '<', 
 
     args: '<' 
 
     }, 
 
     controller: function($scope, $element) { 
 
     var args = $scope.args; 
 
     //console.log(args) 
 
     var argsStr = "" 
 
     if (typeof args !== 'undefined' && args.constructor === Object) { 
 
      for (arg in args) { 
 
      argsStr += ' ' + arg + '="args.' + arg + '"'; 
 
      } 
 
     } 
 
     var elem = "<" + $scope.name + argsStr + "></" + $scope.name + ">"; 
 
     //console.log(elem) 
 
     var component = $compile(elem)($scope)[0]; 
 
     $element.append(component); 
 
     } 
 
    } 
 
    } 
 
]) 
 

 
.controller('ExampleController', ['$scope', 
 
    function($scope) { 
 
     $scope.items = [{ 
 
     component: "alpha", 
 
     args: { 
 
      foo: "first elem" 
 
     } 
 
     }, { 
 
     component: "alpha", 
 
     args: { 
 
      foo: "the last one has no foo" 
 
     } 
 
     }, { 
 
     component: "alpha", 
 
     args: {} 
 
     }]; 
 
    } 
 
    ]) 
 
    .component('alpha', { 
 
    bindings: { 
 
     foo: '<?' 
 
    }, 
 
    template: "this is component alpha. foo arg: {{ $ctrl.foo }}" 
 
    }) 
 
    .component('beta', { 
 
    template: "this is component beta" 
 
    })
<!doctype html> 
 
<html lang="en"> 
 

 
<head> 
 
    <meta charset="UTF-8"> 
 
    <title>Example</title> 
 
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script> 
 
</head> 
 

 
<body ng-app="switchExample"> 
 
    <h2>Procedural component</h2> 
 
    <component name="'alpha'"></component> 
 
    <br> 
 
    <component name="'alpha'" args="{foo:'this was passed!', num:123, obj:{}}"></component> 
 
    <br> 
 
    <div component name="'alpha'" args="{foo:'as was this'}"></div> 
 
    <hr> 
 
    <h2>Looping</h2> 
 
    <div ng-controller="ExampleController"> 
 
    <div ng-repeat="s in items" ng-switch="s.component"> 
 
     <component name="s.component" args="s.args"></component> 
 
    </div> 
 
    </div> 
 
</body> 
 

 
</html>

私は私のコンポーネントを包む余分なHTML要素を取り除くことができませんでしたが、少なくとも私は明示的に許可されているものをループしてものではありませんを伝える必要がありません。

+0

ちょうどこれの大きな欠点を見つけました:それはオブジェクトのコピーを渡すので、Angularの監視機構はうまくいかないでしょう: -/ –

+0

修正しないでください。 –

関連する問題