Angular 1.5:动态加载组件 [英] Angular 1.5: dynamically load a component

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

问题描述

我正在尝试使用AngularJS 1.5及其组件创建某种通用的gridview.我现在要执行的操作的(伪代码)版本:

I am trying to create some sort of generic gridview using AngularJS 1.5 and its components. A (pseudocode) version of what I've got going right now:

// inside <my-grid-component data="data" metadata="metadata">
<div ng-repeat="item in $ctrl.data">
    <my-row-component item="item" metadata="$ctrl.metadata"></my-row-component>
</div

// inside <my-row-component item="item" metadata="metadata">
<div ng-repeat="column in $ctrl.metadata.columns">
    <my-cell-component value="$ctrl.item[column]"></my-cell-component>
</div>

现在<my-cell-component>可以具有一些处理明显情况的基本ng-switch语句,例如值是文本,图像还是其他东西,但是由于该值将被许多人和许多项目使用,因此有可能某人想要在单元格内做一些花哨的和/或高度特定的事情.他们可以用更多的ng-switch来补充<my-cell-component>,但是后来他们搞砸了会损害可维护性的基础框架代码.

Now <my-cell-component>could have some basic ng-switchstatement that handles the obvious cases, like if the value is text or an image or something, but since this will be used by many people and on many projects, it is possible that someone will want to do something fancy and/or highly specific inside a cell. They could just ammend <my-cell-component> with more ng-switches, but then they are messing with base framework code which hurts maintainability.

因此,理想情况下,我想做一些事情,以便开发人员可以选择为元数据中的特定字段提供自己的自定义模板,例如metadata.columns[3].customCellComponentName = 'some-custom-template'; 然后<my-row-component>看起来像这样:

So, ideally, I'd want to make something where a developer can optionally provide his own custom template for a specific field in the metadata, e.g. metadata.columns[3].customCellComponentName = 'some-custom-template'; Then <my-row-component> would look something like this:

<div ng-repeat="column in $ctrl.metadata.columns">
    <div ng-if="!column.isCustomCellComponent">
        <my-cell-component value="$ctrl.item[column]"></my-cell-component>
    </div>
    <div ng-if="column.isCustomCellComponent">
??? --> <column.customCellComponentName value="$ctrl.item[column]"></column.customCellComponentName>
    </div>
</div>

该项目会自动将所有模板放入$ templateCache中,因此解析模板应该不是问题,但是除此之外,带有"???"的标记行显然是行不通的.它演示了我想要实现的目标,但是我不知道如何实际执行这样的操作.我研究了包含法,ng-include和其他解决方案,但似乎都没有提供动态加载模板并对其进行模型绑定的选项.

The project automatically puts all templates in $templateCache, so resolving the template should not be a problem, but other than that, the marked line with the "???" obviously does not work. It demonstrates what I would like to achieve, but I have no idea how to actually do something like this. I looked into transclusion, ng-include and other solutions, but none seem to provide the option to dynamically load a template AND model-bind some data to it.

任何人和所有想法都非常受欢迎.我想尽可能远离过于复杂的指令.尽管它们允许您执行许多操作,但以我的经验,它们也是调试和可维护性的噩梦.

Any and all ideas very much welcome. I would like to stay as far away from overly complex directives as possible. While they allow you to do many things, in my experience they are also a debugging and maintainability nightmare.

谢谢.

推荐答案

您可以为<my-cell-component>创建指令,使其可以接受templateUrl或确定templateUrl并使用它.让我给你一个后者的例子,

You can create a directive for your <my-cell-component> such a way that it either accepts a templateUrl or it determines the templateUrl and uses it. Let me give you an example for the latter,

angular.module('myApp')
    .directive('myCellComponent', ['CELL_TYPE', function (CELL_TYPE) {
        return {
          restrict: 'E',
          scope:{
              cellType: '='
          },
          template: '<div ng-include="templateUrl"></div>',
          link: function (scope) {
              function setTemplate(cellType) {
                  scope.templateUrl = CELL_TYPE[cellType.value].templateUrl;
                  // or figure out some other way to determine templateUrl
              }
              scope.$watch(function () {
                  return scope.cellType;
              }, function (newVal) {
                  if(newVal) {
                      setTemplate(scope.cellType);
                  }
              });
          }
      };
}]);

因此,我们有了带有ng-include的指令模板,该模板使用基于某些常量(例如CELL_TYPE)确定的templateUrl.

So, we've got the directive's template having an ng-include that uses the templateUrl determined on the basis of some constants, say CELL_TYPE.

现在您有了一条指令,可以根据您的属性动态加载其模板!

Now you've got a directive that dynamically loads its template based on your attributes!

如果动态更改templateUrl不适用于您的用例,则可以(显然)摆脱$watch.

You can (obviously) get rid of $watch if dynamically changing the templateUrl isn't applicable to your use-case.

这篇关于Angular 1.5:动态加载组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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