我正在研究我的Ionic 2组件ionic2-autocomplete,它最初是为RC.4和早期版本开发的,现在我正在尝试将它迁移到Angular 2 final。
作为原始设计的一部分,我让开发人员使用接受AutoCompleteItem
或template
的自定义装饰器templateUrl
覆盖默认模板。
可以找到此装饰器的源代码here。
正如您所看到的,我使用装饰器来保留组件所需的一些属性,同时让用户根据自己的需要设计组件。
现在,按照我在文档中写的完全相同的步骤,我尝试使用以下方法实现自定义模板:
import {AutoCompleteItem, AutoCompleteItemComponent} from 'ionic2-auto-complete';
@AutoCompleteItem({
template : `<img src="build/images/flags/{{data.name}}.png" class="flag" /> <span [innerHTML]="data.name | boldprefix:keyword"></span>`,
})
export class CompTestItem extends AutoCompleteItemComponent{
}
在早期版本中完美运行(我还将CompTestItem
添加到declerations
数组中。
但由于某种原因,我现在遇到以下异常:
polyfills.js:3未处理的Promise拒绝:模板解析错误: 多个组件:AutoCompleteItemComponent,CompTestItem(“ [错误 - &gt;];任务:Promise.then; 值:错误:模板解析错误:(...)错误:模板解析错误: 多个组件:AutoCompleteItemComponent,CompTestItem(“ [ERROR - &gt;] http:// localhost:8101 / build / main.js:19480:19) 在RuntimeCompiler._compileTemplate(http://localhost:8101/build/main.js:27855:51) 在http://localhost:8101/build/main.js:27777:83 at Set.forEach(native) 在编译时(http://localhost:8101/build/main.js:27777:47) at t.invoke(http://localhost:8101/build/polyfills.js:3:13400) 在e.run(http://localhost:8101/build/polyfills.js:3:10787) 在http://localhost:8101/build/polyfills.js:3:8889 at t.invokeTask(http://localhost:8101/build/polyfills.js:3:14029) 在e.runTask(http://localhost:8101/build/polyfills.js:3:11389)o @polyfills.js:3r @polyfills.js:3i @polyfills.js:3 polyfills.js:3 错误:未捕获(在承诺中):错误:模板解析错误:(...)o @ polyfills.js:3r @polyfills.js:3i @polyfills.js:3
我真的不知道为什么。任何人都可以知道为什么这个自定义装饰器不会在这个版本的Angular上工作? 为什么说我有多个组件?
谢谢!
答案 0 :(得分:1)
更清楚地解释我的上述评论。看看你的装饰师
export function AutoCompleteItem( config: AutoCompleteItemMetadata ) {
return function(cls: any) {
const _reflect: any = Reflect;
let annotations = _reflect.getMetadata('annotations', cls) || [];
let extendedConfig: any = config;
extendedConfig.selector = 'ion-auto-complete-item';
annotations.push(new Component(extendedConfig));
_reflect.defineMetadata('annotations', annotations, cls);
return cls;
};
}
您正在将每个组件的选择器设置为ion-auto-complete-item
。所以在这种情况下
@AutoCompleteItem({
template: defaultTemplate
})
export class AutoCompleteItemComponent {}
@AutoCompleteItem({})
export class ExtendedComponent extends AutoCompleteComponent {}
现在,您有两个具有相同选择器的组件。现在这一点无所谓。但当他们两个一起进入同一个房间时,Angular无法确定使用哪一个。
现在这可能不需要在早期的RC4中出现问题,因为限制比现在小。在使用仅限于组件
的directives
之前
@Component({
directives: [ AutoCompleteItemComponent ]
})
class SomeComponent {}
在同一个组件中使用AutoCompleteItemComponent
和ExtendedComponent
可能很少见;所以没有冲突。
但不是我们使用模块,组件的范围变得更宽,这为更多冲突留下了空间。
也许你有一个共享模块,你导入到另一个模块
@NgModule({
imports: [ FormsModule, CommonModule ],
declarations: [ AutoCompleteItemComponent ],
exports: [ AutoCompleteItemComponent ]
})
class SharedModule {}
@NgModule({
imports: [ SharedModule ],
declarations: [ ExtendedComponent, ComponentThatUsesExendedComponent ]
exports: [ ComponentThatUsesExtendedComponent ]
})
class OtherModule {}
在上述情况下,您将收到错误消息,因为现在AutoComponentItemComponent
和ExtendedComponent
位于同一个房间。 Angular无法确定在ComponentThatUsesExendedComponent
中使用哪一个,因此您会收到错误
多个组件AutoCompleteItemComponent,ExtendedComponent
此时我不知道你能做些什么来解决这个问题,但只是确保两个组件永远不会在同一个房间里,无论是显式还是隐式。更难的是组件类只能在一个模块中声明。