以角度1.6编程方式加载组件 [英] Load component programmatically in angular 1.6

查看:56
本文介绍了以角度1.6编程方式加载组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个AngularJS 1.6应用程序,它有一个小部件。

I have an AngularJS 1.6 application which has a widget section.

小部件部分是一个包含3个小部件的行,最终用户可以自己配置。他给出了一个所有可用小部件的列表,他可以选择放置哪个小部件。

The widget section is a row with 3 widget that the end user can configure himself. He's given a list of all available widget, and he can choose which one to place and where.

每个小部件都是一个初始化的组件:

Every widget is a component initialized like so:

(
  function(angular) {

    function Module1Controller() {
      var vm = this;

      // other stuff here
    }

    angular.module("app")
      .component(
        "module1", {
          controller: Module1Controller,
          templateUrl: 'module1.html'
        }  
      );
  }
)(angular)

现在,由于用户可以选择在特定位置呈现哪个小部件,因此该数据来自web服务。

Now, since the user can select which widget to render in a specific position, this data comes from a webservice.

根据从WS收到的数据,我需要能够激活一个组件并停用所有其他组件。

Based on the data received from the WS, I need to be able to "activate" a component and "deactivate" all other components.

我的第一个想法是这样做:

My first thought was to do something like so:

控制器:

(
  function(angular) {

    function ModulesController() {
      var vm = this;

      vm.firstModule = 1;
      vm.secondModule = 1;
      vm.thirdModule = 1;

      vm.availableModules = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    }

    angular.module("app")
      .controller(
        "ModulesController", 
        [
          ModulesController
        ]
      );
  }
)(angular)

查看:

<div class="container-fluid" ng-controller="ModulesController as c">
    <div class="row">
        <div class="col-xs-4"> <!-- third widget area -->
            <module-1 ng-if="c.firstModule == 1"></module-1>
            <module-2 ng-if="c.firstModule == 2"></module-2>
            <module-3 ng-if="c.firstModule == 3"></module-3>
            <module-4 ng-if="c.firstModule == 4"></module-4>
            <module-5 ng-if="c.firstModule == 5"></module-5>
            <module-6 ng-if="c.firstModule == 6"></module-6>
            <module-7 ng-if="c.firstModule == 7"></module-7>
            <module-8 ng-if="c.firstModule == 8"></module-8>
            <module-9 ng-if="c.firstModule == 9"></module-9>
            <module-10 ng-if="c.firstModule == 10"></module-10>
        </div>
        <div class="col-xs-4"> <!-- third widget area -->
            <module-1 ng-if="c.secondModule == 1"></module-1>
            <module-2 ng-if="c.secondModule == 2"></module-2>
            <module-3 ng-if="c.secondModule == 3"></module-3>
            <module-4 ng-if="c.secondModule == 4"></module-4>
            <module-5 ng-if="c.secondModule == 5"></module-5>
            <module-6 ng-if="c.secondModule == 6"></module-6>
            <module-7 ng-if="c.secondModule == 7"></module-7>
            <module-8 ng-if="c.secondModule == 8"></module-8>
            <module-9 ng-if="c.secondModule == 9"></module-9>
            <module-10 ng-if="c.secondModule == 10"></module-10>
        </div>
        <div class="col-xs-4"> <!-- third widget area -->
            <module-1 ng-if="c.thirdModule == 1"></module-1>
            <module-2 ng-if="c.thirdModule == 2"></module-2>
            <module-3 ng-if="c.thirdModule == 3"></module-3>
            <module-4 ng-if="c.thirdModule == 4"></module-4>
            <module-5 ng-if="c.thirdModule == 5"></module-5>
            <module-6 ng-if="c.thirdModule == 6"></module-6>
            <module-7 ng-if="c.thirdModule == 7"></module-7>
            <module-8 ng-if="c.thirdModule == 8"></module-8>
            <module-9 ng-if="c.thirdModule == 9"></module-9>
            <module-10 ng-if="c.thirdModule == 10"></module-10>
        </div>
    </div>
</div>

这样可行,但我觉得这样做是错误的。如果我有200个小部件怎么办?我必须写< module-N ng-if =c.firstModule == N>< / module-N> 200次(x3小部件区域) ),这显然不是解决问题的好方法。

This works, but I feel it's the wrong way to do it. What if I have 200 widgets? I would have to write <module-N ng-if="c.firstModule == N"></module-N> 200 times (x3 widget areas), which is clearly not a good way to solve the issue.

我还想用 ng-include ,但作为faras,我知道它只适用于包含模板,我需要相应的控制器也可以加载。

I also thought to use ng-include, but as faras I know it only works for including templates, I need the corresponding controller to get loaded too.

这是一个关于我的工作示例我试图实现: https://plnkr.co/edit/uO8SUcmNMOGHcPjc1lWs?p=preview

Here is a plunker showing a working example of what I'm trying to achieve: https://plnkr.co/edit/uO8SUcmNMOGHcPjc1lWs?p=preview

如您所见,当您更改组合的值时,相应的模块将被替换。

As you can see, when you change the value of a combo, the corresponding module gets replaced.

问题是:有没有办法根据AngularJS 1.6中的某个控制器字段激活特定组件,而不必声明所有组件并使用 ng-if

The question is: is there a way to activate a specific component based on some controller field in AngularJS 1.6 without having to declare all of them and use ng-if?

推荐答案

正如我在评论部分所建议的那样,哟你可以使用 module-slot 指令并将模块作为一种模型输入,并在内部解析所需模块的加载和编译。

As I suggested in the comments section, you can use a module-slot directive and input the module as a sort of model, and internally resolve either the loading and compilation of the desired module.

此解决方案使用 ocLazyLoad ,但如果您需要,可以使用其他装载程序。

This solution uses ocLazyLoad but you can use other loader if you want.

我做了一个叉子您的plunkr使用ocLazyLoading的解决方案

所以,不要声明所有模块并使用 ng-if 你只使用一个这样的指令:

So, instead of declaring all modules and control its visibility with ng-if you use only one directive like so:

<div class="row">
    <div class="col-xs-4">
      <module-slot module="c.firstModule"></module-slot>
    </div>
    <div class="col-xs-4">
      <module-slot module="c.secondModule"></module-slot>
    </div>
    <div class="col-xs-4">
      <module-slot module="c.thirdModule"></module-slot>
    </div>
  </div>

指令:

angular.module("app")
    .directive('moduleSlot', function($ocLazyLoad, $compile) {
      return {
        restrict: 'E',
        scope: {
          module: '='
        },
        link: function(scope, element, attrs) {
          // watch the module change
          scope.$watch('module', function() {
            // load the module
            $ocLazyLoad.load("module" + scope.module + ".js").then(function() {
              // compiles the new component inside the slot
              element.html("<module-" + scope.module + "></module-" + scope.module + ">");
              $compile(element.contents())(scope);

            }, function(e) {
              console.log('errr');
              console.error(e);
            })
          });
        }
      }
    });




参考

Refs

OcLazyLoad Docs

来自ocLazyLoad存储库的简单示例

$ compile service docs

这篇关于以角度1.6编程方式加载组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆