web-dev-qa-db-ja.com

Angular(1.5.8)動的コンポーネント

Angular 1.5.8。を使用して、一種の動的ダッシュボードを構築しようとしています。最後のハードルまでかなりの進歩を遂げました。これが実際に動的コンポーネントをレンダリングしています。

私は2つのオプションを試しましたが、ui-viewおよびプログラムでウィジェットの名前を渡しますor、これは私が推測しているルートですmore正しいです。レンダリング方法を理解する必要があります動的ウィジェット。

例:dashItemsコレクションに項目を追加すると、(提供した名前に基づいて)新しいウィジェットがレンダリングされます。

ngIncludeを使用してテンプレートを交換できることを確認しましたが、テンプレートとコントローラーを動的に挿入する方法についてはまだ不明です。 (たとえば、すべてのテンプレートが共通のコントローラーを共有することはありません)。

JavaScript:

angular
    .module('myDashboard', [])
    .config(routesConfig)
    .component('dashboard', {
        templateUrl: 'dashboard/dashboard.tpl.html',
        controller: dashboardController
    })
    .component('widgetPie', {
        template: '<h3>Pie Graph</h3>',
        controller: function($log) {
            $log.info('widgetPie: loaded');
        }
    })
    .component('widgetLine', {
        template: '<h3>Line Graph</h3>',
        controller: function($log) {
            $log.info('WidgetLine: loaded');
        }
    });

function routesConfig($stateProvider) {
    // this is only needed if I go the ui-view route.. I assume
    $stateProvider
        .state('widgetPie', { component: 'widgetPie'})
        .state('widgetLine', { component: 'widgetLine'});
}

function dashboardController($log) {
    $log.info('in dashboard');
    this.dashItems = [
        { widget:'widgetPie' },
        { widget:'widgetLine' }
    ];
}

マークアップ(dashboard/dashboard.tpl.html):

<div>
    <ul>
        <li ng-repeat="item in dashItems">
            <!--somehow render dynamic-->
            <!--<widget-pie></widget-pie>-->
            <!--<div ui-view="item.widget"></div>-->
        </li>
    </ul>
</div>

質問:

1. ngIncludeを調査しましたが、完全に正直に言うと、このインスタンスでどのように使用するかがわかりません。これがこのための適切なツールであるか、またはこれに取り組んでいますか?間違って?

2.このために状態プロバイダーにアイテムを追加する必要がある場合でも、EG i /ウィジェットを子状態として表示できます(したがって、何がベストプラクティスとして表示されるかわかりません)

16
Rohan Büchner

dashboard.tpl.htmlファイルから:

<div>
    <ul>
        <li ng-repeat="item in dashItems">
            <div ng-include="item.widget"></div>
        </li>
    </ul>
</div>

しかし、自分のウィジェットフォルダーを介して実行するビルドタスクを追加し、以下を生成することも必要でした(または、私が推測するボートのフロートが何であれ、手動で追加することもできます)。

angular
 .module('myDashboard')
 .run(function ($templateCache) {
    $templateCache.put('widgetPie', '<widget-pie></widget-pie>');
    $templateCache.put('widgetLine', '<widget-line></widget-line>');
 });

上記により、templateUrlまたはインラインテンプレートを使用できます。

.component('widgetPie', {
   templateUrl: 'dashboard/widgetPie.tpl.html',
   controller: function($log) {
      $log.info('widgetPie: loaded');
   }
})
.component('widgetLine', {
    template: '<h1>Some Content</h1>',
    controller: function($log) {
      $log.info('widgetLine: loaded');
    }
})
21
Rohan Büchner

できます。まず、動的コンポーネントのコンパイルに役立つラッパーコンポーネントを使用する必要があります。

app.component('dynamicWrapper',
    {
        controller: function widgetClientCtrl($scope, $compile, $element) {
                    var self = this;
                    self.$onInit = function () {
                          renderWidget(self.name, self.payload);
                    };
                    function renderWidget(name, payload) {
                          var template = '<' + name;

                          if (payload) {
                             $scope.payload = payload;
                             template += ' payload="payload"';
                          }

                          template += '></' + name + '>';
                          $element.append($compile(template)($scope));
                    }
        },
        bindings: {
            name: '@',
            payload: '=?'
        }
    });

あなたの動的コンポーネント:

app.component('someDynamicComponent', {
    templateUrl: 'yourPath',
    controller: dynamicComponentCtrl,
    controllerAs: 'vm',
    bindings: {
        payload: '<'
    }
});

その後:

<li ng-repeat="(name, payload) in vm.dynamicComponents">
      <dynamic-wrapper name="{{name}}" payload="payload"></dynamic-wrapper>
</li>
3