[英]Upgraded AngularJS component which requires another upgraded component can't find the parent controller when using Angular content projection
I am trying to do a PoC for ngUpgrade on one module of my app, and I'm running into an issue with transclusion/content projection along with AngularJS requires
. 我试图做ngUpgrade的PoC我的应用程序的一个模块上,我正在与transclusion /内容投影的问题与AngularJS一起
requires
。
Let's say there's a downgraded Angular component defined like: 假设有一个降级的Angular组件,定义如下:
@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 {}
ajsButton
is an upgraded AngularJS component that requires a parent controller: ajsButton
是需要父控制器的升级的AngularJS组件:
require: {
ajsFilterCtrl: '^ajsFilter'
}
A normal use of common-filter
works perfectly fine, however when projecting an ajs-button
like: 正常使用
common-filter
可以很好地工作,但是在投影ajs-button
例如:
<common-filter>
<ajs-button text="Inside of content projection"></ajs-button>
</common-filter>
This error is thrown: 引发此错误:
Unhandled Promise rejection: [$compile:ctreq] Controller 'ajsFilter', required by directive 'ajsButton', can't be found!
Is there any way around this? 有没有办法解决? I know that I can rewrite the surrounding classes, but many other apps use them and I need to be able to upgrade the apps gradually.
我知道我可以重写周围的类,但是许多其他应用程序都使用它们,因此我需要能够逐步升级这些应用程序。
Working Example: 工作示例:
https://stackblitz.com/edit/ngupgradestatic-playground-uvr14t https://stackblitz.com/edit/ngupgradestatic-playground-uvr14t
Snippets above are from index.html
and common-filter.component.ts
. 上面的代码片段来自
index.html
和common-filter.component.ts
。 This is a (more-or-less) minimal example based on much more complicated components. 这是一个(或多或少)基于更复杂组件的最小示例。 I'm going with the
downgradeModule
approach for performance reasons. 由于性能原因,我将使用
downgradeModule
方法。
A maintainer, gkalpak, provided a workaround for this issue in the Github issue that I posted for this: https://github.com/angular/angular/issues/24846#issuecomment-404448494 维护者gkalpak在我为此发布的Github问题中提供了针对此问题的解决方法: https : //github.com/angular/angular/issues/24846#issuecomment-404448494
In short, this is an issue with the order of initialization of the different controllers. 简而言之,这是不同控制器初始化顺序的问题。 To get around it, you can make the parent
require
optional and then use setTimeout
to wait until the parent controller is initialized: 为了解决这个问题,您可以使父级
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);
});
});
};
The workaround can be seen in action here: https://stackblitz.com/edit/ngupgradestatic-playground-a6zkwb 可以在此处查看解决方法: https : //stackblitz.com/edit/ngupgradestatic-playground-a6zkwb
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.