我正在尝试在我的应用程序的一个模块上为ngUpgrade进行PoC,但是我遇到了与AngularJS "root": "libs/my-lib",
"sourceRoot": "libs/my-lib/src"
一起使用的包含/内容投影的问题。
假设有一个降级的Angular组件,定义如下:
requires
@Component({
selector: 'common-filter',
template: `
<ajs-filter>
<div>Common Filter</div>
<ajs-button text="Outside of content projection"></ajs-button>
<ng-content></ng-content>
</ajs-filter>
})
export class CommonFilter {}
是需要父控制器的升级的AngularJS组件:
ajsButton
正常使用require: {
ajsFilterCtrl: '^ajsFilter'
}
可以很好地工作,但是在投影common-filter
时像这样:
ajs-button
抛出此错误:
<common-filter>
<ajs-button text="Inside of content projection"></ajs-button>
</common-filter>
有什么办法解决吗?我知道我可以重写周围的类,但是许多其他应用程序都在使用它们,并且我需要能够逐渐升级这些应用程序。
工作示例:
https://stackblitz.com/edit/ngupgradestatic-playground-uvr14t
上面的摘录来自Unhandled Promise rejection: [$compile:ctreq] Controller 'ajsFilter', required by directive 'ajsButton', can't be found!
和index.html
。这是一个(或多或少)基于更复杂组件的最小示例。出于性能原因,我将使用common-filter.component.ts
方法。
答案 0 :(得分:0)
维护者gkalpak在我为此发布的Github问题中提供了解决此问题的方法: https://github.com/angular/angular/issues/24846#issuecomment-404448494
简而言之,这是不同控制器初始化顺序的问题。 要解决此问题,可以将父require
设为可选,然后使用setTimeout
等到父控制器初始化后:
this.$onInit = () => {
this.requireAjsFilterCtrl().then(() => console.log('!', !!this.ajsFilterCtrl));
}
this.requireAjsFilterCtrl = () => {
return new Promise(resolve => {
setTimeout(() => {
this.ajsFilterCtrl = this.ajsFilterCtrl || $element.controller('ajsFilter');
resolve(this.ajsFilterCtrl);
});
});
};
可以在此处查看解决方法: https://stackblitz.com/edit/ngupgradestatic-playground-a6zkwb