Angular元素两次调用组件构造函数 [英] Component constructor is getting called twice with Angular elements
问题描述
我正在处理一个递归查询生成器表单,该表单类似于中的此 >角7,具有反应形式。意味着,用户可以通过单击添加规则
来继续添加并行规则,也可以通过单击添加组
。
我创建了两个组件, QueryDesignerComponent
和 QueryComponent
。 QueryDesignerComponent
保存外部容器,条件为 AND
和 OR
和 QueryComponent
保存行输入,即 LHS
, operator
和 RHS
。
- 当用户单击
添加规则
时,我只是通过再推一个来扩展规则QueryDesignerComponent
中包含QueryComponent
的条目。我用* ngFor
重复此操作。 - 当用户单击
添加组
我在QueryComponent
内调用QueryDesignerComponent
,这使其递归。我用* ngFor
重复一遍。
我已经完成了实现并在带有角度环境的角度应用中正常工作。
现在,我正在尝试将此流移植到角度元素,以使其可重复使用,无论环境如何。
这就是我将第一行[ QueryComponent
]放在 QueryDesignerComponent $内的方式c $ c>,
< div class = qd--criteria > < div class = row qd--body qd--clear-margin-lr> < div class = col-md-12 qd--condition-container> < query [data] = data [operators] = operators [(queryForm)] = queryForm>< / query> < / div> < / div>< / div>
我正在管理 QueryComponent
内的并行查询和组,
<!-查询视图的顶级容器|所有相关的内容都应在此处:start->< div class = qd--query-container [formGroup] = queryForm * ngIf = queryForm> < div class = row formArrayName = queries> < ;!-重复动态添加/删除的查询:start-> < div class = col-md-12 qd--query-inputs-container * ngFor =让对currentQueries.controls的查询;让queryIndex = index> < div class = row qd--query-inputs [formGroupName] = queryIndex> <!-实际查询输入:start-> < div class = col-md-10 qd--condition-holder> < div class = row no-gutter> <!-左手侧输入:开始-> <!-左手侧输入:结束-> <!-操作员:开始-> <!-运算符:end-> <!-右侧输入:开始-> <!-右侧输入:结束-> < / div> < / div> <!-实际查询输入:start-> <!-组选项:开始-> <!-组选项:end-> <!-组查询:开始-> < div * ngIf = query!==未定义 class = ai--query-groups> < div * ngFor =让getGroups(query).controls的组;让groupIndex = index class = ai--query-group> < query-designer [data] = data [operators] = operators [queryForm] = group(removeQueryGroup)= removeQueryGroupHandler($ event) [queryIndex] = queryIndex [groupIndex] = groupIndex >< / query-designer> < / div> < / div> <!-组查询:end-> < / div> < / div> < ;!-重复动态添加/删除的查询:end-> < / div>< / div>< ;!-查询视图的顶层容器:start-< !!-重复动态添加/删除的查询:start->< div class = col-md-12 qd--query-inputs-container * ngFor =让查询currentQueries.controls;让queryIndex = index> < div class = row qd--query-inputs [formGroupName] = queryIndex> <!-实际查询输入:start-> < div class = col-md-10 qd--condition-holder> < div class = row no-gutter> <!-左手侧输入:开始-> <!-左手侧输入:结束-> <!-操作员:开始-> <!-运算符:end-> <!-右侧输入:开始-> <!-右侧输入:结束-> < / div> < / div> <!-实际查询输入:start-> <!-组选项:开始-> <!-组选项:end-> <!-组查询:开始-> < div * ngIf = query!==未定义 class = ai--query-groups> < div * ngFor =让getGroups(query).controls的组;让groupIndex = index class = ai--query-group> < query-designer [data] = data [operators] = operators [queryForm] = group(removeQueryGroup)= removeQueryGroupHandler($ event) [queryIndex] = queryIndex [groupIndex] = groupIndex >< / query-designer> < / div> < / div> <!-组查询:end-> < / div>< / div>< ;!-重复动态添加/删除的查询:end->
这就是我创建自定义角度元素的方式,
@NgModule({
进口:[
CommonModule,
BrowserModule,
NgSelectModule,
FormsModule,
ReactiveFormsModule,
CoreModule
],
声明:[
AppComponent,
QueryComponent,
QueryDesignerComponent
],
entryComponents:[QueryDesignerComponent],
提供者:[]
})
导出类AppModule {
构造函数(私有注入器:Injector){
const strategyFactory = new ElementZoneStrategyFactory(QueryDesignerComponent,jector);
const customElement = createCustomElement(QueryDesignerComponent,{jector,strategyFactory));
customElements.define('query-designer',customElement);
}
ngDoBootstrap(){}
}
在第一个渲染中,它工作正常,我能够添加 n
个并行行。但是,当我单击添加组
时, QueryDesignerComponent
的构造函数被调用了两次!这使得 QueryDesignerComponent
的第一个实例接收 undefined
,第二个实例接收正确的值。
我关注了为什么ngOnInit被调用了两次?,与 github问题和,但是我发现没有运气!
有人知道怎么做吗?我可以摆脱这个问题吗?任何帮助/指导都将不胜感激!
我对Angular Elements也遇到了同样的问题。
问题是我在Angular7组件内调用了Angular7组件,在app.module.ts上我用与Angular7组件名称相同的名称自举了子组件。 p>
当父级调用my-child-component时,它同时调用了Angular7和Custom Element。
,解决方法是在这种情况下使用其他名称。
I am working on a recursive query builder form, which is something similar to this, in angular 7, with reactive form. Means, the user can keep adding a parallel rule by clicking on Add rule
and can add a group by clicking on Add group
.
I have created two components, QueryDesignerComponent
and QueryComponent
. QueryDesignerComponent
holds the outer container, with AND
and OR
condition and QueryComponent
holds the row input, that's LHS
, operator
and RHS
.
- When user clicks
Add rule
I am growing the rule just by pushing one more entry withQueryComponent
insideQueryDesignerComponent
. I am repeating this with*ngFor
. - When the user clicks
Add group
I am callings theQueryDesignerComponent
insideQueryComponent
, which makes it recursive. I am repeating this with*ngFor
.
I am done with the implementation and its working fine within angular app, which has an angular environment.
Now, I am trying to port this flow in angular elements, to make it reusable, regardless of the environment.
this is how I am placing first row [ QueryComponent
] inside QueryDesignerComponent
,
<div class="qd--criteria">
<div class="row qd--body qd--clear-margin-lr">
<div class="col-md-12 qd--condition-container">
<query [data]="data" [operators]="operators" [(queryForm)]="queryForm"></query>
</div>
</div>
</div>
and this way I am managing the parallel query and groups inside QueryComponent
,
<!--Top level container for query view | everything related should go here: start-->
<div class="qd--query-container" [formGroup]="queryForm" *ngIf="queryForm">
<div class="row" formArrayName="queries">
<!--Repeat the dynamically added/removed queries: start-->
<div class="col-md-12 qd--query-inputs-container" *ngFor="let query of currentQueries.controls; let queryIndex = index">
<div class="row qd--query-inputs" [formGroupName]="queryIndex">
<!--Actual query inputs: start-->
<div class="col-md-10 qd--condition-holder">
<div class="row no-gutter">
<!--Left hand side input: start-->
<!--Left hand side input: end-->
<!--Operator: start-->
<!--Operator: end-->
<!--Right hand side input: start-->
<!--Right hand side input: end-->
</div>
</div>
<!--Actual query inputs: start-->
<!--Group options: start-->
<!--Group options: end-->
<!--Group query: start-->
<div *ngIf="query !== undefined" class="ai--query-groups">
<div *ngFor="let group of getGroups(query).controls; let groupIndex=index" class="ai--query-group">
<query-designer
[data]="data"
[operators]="operators"
[queryForm]="group"
(removeQueryGroup)="removeQueryGroupHandler($event)"
[queryIndex]="queryIndex"
[groupIndex]="groupIndex"></query-designer>
</div>
</div>
<!--Group query: end-->
</div>
</div>
<!--Repeat the dynamically added/removed queries: end-->
</div>
</div>
<!--Top level container for query view: start-->
<!--Repeat the dynamically added/removed queries: start-->
<div class="col-md-12 qd--query-inputs-container" *ngFor="let query of currentQueries.controls; let queryIndex = index">
<div class="row qd--query-inputs" [formGroupName]="queryIndex">
<!--Actual query inputs: start-->
<div class="col-md-10 qd--condition-holder">
<div class="row no-gutter">
<!--Left hand side input: start-->
<!--Left hand side input: end-->
<!--Operator: start-->
<!--Operator: end-->
<!--Right hand side input: start-->
<!--Right hand side input: end-->
</div>
</div>
<!--Actual query inputs: start-->
<!--Group options: start-->
<!--Group options: end-->
<!--Group query: start-->
<div *ngIf="query !== undefined" class="ai--query-groups">
<div *ngFor="let group of getGroups(query).controls; let groupIndex=index" class="ai--query-group">
<query-designer
[data]="data"
[operators]="operators"
[queryForm]="group"
(removeQueryGroup)="removeQueryGroupHandler($event)"
[queryIndex]="queryIndex"
[groupIndex]="groupIndex"></query-designer>
</div>
</div>
<!--Group query: end-->
</div>
</div>
<!--Repeat the dynamically added/removed queries: end-->
This is how I am creating a custom angular element,
@NgModule({
imports: [
CommonModule,
BrowserModule,
NgSelectModule,
FormsModule,
ReactiveFormsModule,
CoreModule
],
declarations: [
AppComponent,
QueryComponent,
QueryDesignerComponent
],
entryComponents: [QueryDesignerComponent],
providers: []
})
export class AppModule {
constructor(private injector: Injector) {
const strategyFactory = new ElementZoneStrategyFactory(QueryDesignerComponent, injector);
const customElement = createCustomElement(QueryDesignerComponent, { injector, strategyFactory });
customElements.define('query-designer', customElement);
}
ngDoBootstrap() { }
}
In the first render, it's working fine and I am able to add n
number of parallel rows. But, when I click the Add group
, QueryDesignerComponent
's constructor is getting called twice! This makes the first instance of QueryDesignerComponent
to receive undefined
and second instance to receive correct values.
I followed why ngOnInit called twice?, related github issue and ngOnInit and Constructor are called twice but, I found no luck!!
Does anyone know how can I get rid of this issue? Any help/guidance would be much appreciated!
I just had the same issue, with Angular Elements too.
Problem was that I was calling an Angular7 component inside an Angular7 component, and on app.module.ts I had bootstrapped the child component with the same name as the Angular7 component name.
When parent called my-child-component it was calling both the Angular7 one and the Custom Element one.
So, the fix is to use different names in this case.
这篇关于Angular元素两次调用组件构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!