【问题标题】:Angular (1.5.8) Dynamic ComponentsAngular (1.5.8) 动态组件
【发布时间】:2017-03-30 17:46:53
【问题描述】:

我正在尝试使用 Angular 1.5.8 构建一种动态仪表板。直到最后一关,我都取得了不错的进展。这实际上是在渲染动态组件。

我尝试了 2 个选项,添加 ui-view 并以编程方式传入小部件的名称,,这是我猜测的路径 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 / 小部件是否可以被视为子状态(因此我不确定什么会被视为最佳实践)

【问题讨论】:

  • 你读过指令吗?
  • @LarryTurtis 是的,我熟悉指令以及它们在大多数情况下是如何工作的,但不是关于让它们(或组件)动态渲染,例如在我的问题中,我仍然有点在黑暗中
  • 我可能误解了意图,但是您能否像this post 中所述那样动态编译指令并将它们添加到页面中?
  • @estus 如果我错了,请纠正我(我可能/可能是),但我不想只是动态换出模板......因此他们不会在背部。我想换掉一个动态模板和控制器?这不是另一种情况吗?
  • 模板应包含所需的组件。

标签: angularjs dynamic components angularjs-ng-include


【解决方案1】:

我最终将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');
    }
})

【讨论】:

  • 在这种情况下,如果我必须将数据从 ng-include 传递给小部件,这怎么可能?
  • @AnkurArora 我已经有几年没有从事 Angular 工作了:P 但我想注入一个允许您传递数据的共享服务或存储将允许您访问数据不同的组件。例如controller: function($log, $yourService, $yourStore) { }
  • 感谢您的回复。如果数据是共享的,服务会很棒,但在这种情况下,我希望它是一个组件。我用其他方式解决了,再次感谢。
【解决方案2】:

你可以做到。首先,您需要使用包装器组件来帮助您编译动态组件:

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>

【讨论】:

    猜你喜欢
    • 2017-07-06
    • 1970-01-01
    • 1970-01-01
    • 2017-07-18
    • 2019-07-26
    • 2019-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多