Angular 1.5:动态加载组件 [英] Angular 1.5: dynamically load a component
问题描述
我正在尝试使用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-switch
statement 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-switch
es, 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屋!