AG Grid:通过 ComponentFactoryResolver 在组件中加载网格时未触发 gridReady 事件
AG Grid : gridReady event not triggered when loading grid in a component via ComponentFactoryResolver
在我的 Angular 10 应用程序中,我正在通过组件工厂解析器加载一个包含 AG 网格的组件。
当我通过按钮触发工厂解析器时,一切正常。显示网格并正确触发 gridReady
事件。
但是,如果我通过 ngOnInit()
或 ngAfterViewInit()
等触发组件工厂解析器,则不会触发 gridReady 事件并且不会显示网格。
我尝试使用 ChangeDetectorRef 服务来强制进行更改检测,但这并没有改变任何东西。
这是组件工厂解析器的代码:
export class PlannerComponent implements OnInit {
@ViewChild('ordersContainer', {read: ViewContainerRef}) container: ViewContainerRef;
public orders = [];
constructor(
private componentFactoryResolver: ComponentFactoryResolver,
private httpClient: HttpClient
) { }
ngOnInit(): void {
this.loadOpenOrders();
}
loadOpenOrders() {
this.httpClient.get('/orders')
.pipe(map((result: any) => {
const orders = result._embedded.orders;
orders.forEach((function (order) {
this.addOrder();
}).bind(this))
}))
.subscribe()
}
onGridReady(params) {
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
this.gridApi.sizeColumnsToFit();
}
addOrder() {
// Create component dynamically inside the ng-template
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(OrderComponent);
const newOrder = this.container.createComponent(componentFactory);
// Push the component so that we can keep track of which components are created
this.orders.push(newOrder);
}
}
在视图中,组件是这样加载的:
<div class="container">
<div class="row">
<div class="col-6">
<div class="card card-custom gutter-b">
<ag-grid-angular
style="width: 100%; height: 600px;"
class="ag-theme-alpine"
[rowData]="ordersToPlan"
[columnDefs]="columnDefs"
[rowSelection]="rowSelectionType"
(gridReady)="onGridReady($event)" <==== Only triggered through button click, but not on ngOnInit()
[animateRows]="true"
>
</ag-grid-angular>
</div>
</div>
<div class="col-6">
<button class="btn btn-success mb-5" (click)="addOrder()">Add a new Order</button>
<div>
<ng-template #ordersContainer>
</ng-template>
</div>
</div>
</div>
</div>
感谢任何帮助:-)
我发现您的代码中有一处存在问题。
与其在 pipe
运算符中调用 addOrders
,不如在 get
调用的 subscribe
部分完成。
loadOpenOrders() {
this.httpClient.get('/orders')
.subscribe((result: any) => {
const orders = result._embedded.orders;
orders.forEach(order => {
this.addOrder();
});
});
}
为什么我认为这会有所帮助? - 也许变更检测周期可能与 rxjs Observable
的 subscribe
有关;由于您的代码正在做所有这些事情 before/outside subscribe
,它可能会被循环遗漏。
由于我无法将这些代码作为评论,因此将其发布为答案。让我知道这个是否奏效。评论你得到的任何错误/你的观察。如果你能提供任何工作示例(plunk/stackblitz),将能够快速帮助你。
如果没有帮助,将删除此答案。
试试这个:
转换
public orders = [];
进入 Observable:
private ordersBS = new BehaviourSubject<any[]>([]);
public orders$ = this.ordersBS.asObservable();
HTML:
[rowData]="orders$ | async"
添加订单时:
this.ordersBS.next(newOrder);
这样 agGrid 将始终监听 orders$ observable。
onGridReady 函数应该只调用一次。
终于找到问题了。我需要强制执行更改检测,但是在子组件中(我通过组件工厂解析器加载的组件)。
在order.component.ts
中:
constructor(
private cd: ChangeDetectorRef
) { }
...
setTransport(transport: Transport): void {
...
this.cd.detectChanges();
}
非常感谢所有尝试解决此问题的人!
在我的 Angular 10 应用程序中,我正在通过组件工厂解析器加载一个包含 AG 网格的组件。
当我通过按钮触发工厂解析器时,一切正常。显示网格并正确触发 gridReady
事件。
但是,如果我通过 ngOnInit()
或 ngAfterViewInit()
等触发组件工厂解析器,则不会触发 gridReady 事件并且不会显示网格。
我尝试使用 ChangeDetectorRef 服务来强制进行更改检测,但这并没有改变任何东西。
这是组件工厂解析器的代码:
export class PlannerComponent implements OnInit {
@ViewChild('ordersContainer', {read: ViewContainerRef}) container: ViewContainerRef;
public orders = [];
constructor(
private componentFactoryResolver: ComponentFactoryResolver,
private httpClient: HttpClient
) { }
ngOnInit(): void {
this.loadOpenOrders();
}
loadOpenOrders() {
this.httpClient.get('/orders')
.pipe(map((result: any) => {
const orders = result._embedded.orders;
orders.forEach((function (order) {
this.addOrder();
}).bind(this))
}))
.subscribe()
}
onGridReady(params) {
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
this.gridApi.sizeColumnsToFit();
}
addOrder() {
// Create component dynamically inside the ng-template
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(OrderComponent);
const newOrder = this.container.createComponent(componentFactory);
// Push the component so that we can keep track of which components are created
this.orders.push(newOrder);
}
}
在视图中,组件是这样加载的:
<div class="container">
<div class="row">
<div class="col-6">
<div class="card card-custom gutter-b">
<ag-grid-angular
style="width: 100%; height: 600px;"
class="ag-theme-alpine"
[rowData]="ordersToPlan"
[columnDefs]="columnDefs"
[rowSelection]="rowSelectionType"
(gridReady)="onGridReady($event)" <==== Only triggered through button click, but not on ngOnInit()
[animateRows]="true"
>
</ag-grid-angular>
</div>
</div>
<div class="col-6">
<button class="btn btn-success mb-5" (click)="addOrder()">Add a new Order</button>
<div>
<ng-template #ordersContainer>
</ng-template>
</div>
</div>
</div>
</div>
感谢任何帮助:-)
我发现您的代码中有一处存在问题。
与其在 pipe
运算符中调用 addOrders
,不如在 get
调用的 subscribe
部分完成。
loadOpenOrders() {
this.httpClient.get('/orders')
.subscribe((result: any) => {
const orders = result._embedded.orders;
orders.forEach(order => {
this.addOrder();
});
});
}
为什么我认为这会有所帮助? - 也许变更检测周期可能与 rxjs Observable
的 subscribe
有关;由于您的代码正在做所有这些事情 before/outside subscribe
,它可能会被循环遗漏。
由于我无法将这些代码作为评论,因此将其发布为答案。让我知道这个是否奏效。评论你得到的任何错误/你的观察。如果你能提供任何工作示例(plunk/stackblitz),将能够快速帮助你。
如果没有帮助,将删除此答案。
试试这个:
转换
public orders = [];
进入 Observable:
private ordersBS = new BehaviourSubject<any[]>([]);
public orders$ = this.ordersBS.asObservable();
HTML:
[rowData]="orders$ | async"
添加订单时:
this.ordersBS.next(newOrder);
这样 agGrid 将始终监听 orders$ observable。
onGridReady 函数应该只调用一次。
终于找到问题了。我需要强制执行更改检测,但是在子组件中(我通过组件工厂解析器加载的组件)。
在order.component.ts
中:
constructor(
private cd: ChangeDetectorRef
) { }
...
setTransport(transport: Transport): void {
...
this.cd.detectChanges();
}
非常感谢所有尝试解决此问题的人!