@ViewChild
在以下情况下,我无法正确初始化带注释的字段:
@ViewChild
带注释的字段undefined
在某些情况下会保留:
- type的父组件
X
实现了type的抽象基类XBase
,它具有三个抽象字段 - 类型的组件用类型注释
X
这些字段,并且@ChildView
A
B
C
C
反过来也扩展XBase
,但使用不同的模板和选择器X
- 类型字段
A
并B
在类型组件中初始化属性X
- 类型字段
C
未定义
这是我的代码的缩短版本
@Component({
moduleId: module.id,
selector: 'drive-view'
templateUrl: './../../html/drive-view.html'
})
export class DriveViewComponent extends GridView<Drive>
{
@ViewChild(DriveGridComponent)
public grid: DriveGridComponent;
@ViewChild(DriveDetailsComponent)
public itemDetails: DriveDetailsComponent;
@ViewChild(DriveFilterModalComponent)
public filterModal: DriveFilterModalComponent;
@ViewChild(DriveMembersModalComponent)
public driveMembersModal: DriveMembersModalComponent;
}
export abstract class GridView<TEntity>
{
public abstract grid: Grid<TEntity>;
public abstract filterModal: IGridFilterModal;
public abstract itemDetails: IGridItemDetails<TEntity>;
}
export abstract class Grid<TEntity>
{
public abstract header: IGridHeader;
public abstract body: IGridBody<TEntity>;
}
@Component({
moduleId: module.id,
selector: '[drive-grid]',
templateUrl: './../../html/grid.html'
})
export class DriveGridComponent extends Grid<Drive>
{
@ViewChild(DriveGridHeaderComponent)
public header: DriveGridHeaderComponent;
@ViewChild(DriveGridBodyComponent)
public body: DriveGridBodyComponent;
}
@Component({
moduleId: module.id,
selector: 'thead [grid-header]',
templateUrl: './../../html/drive-grid-header.html'
})
export class DriveGridHeaderComponent implements IGridHeader
{
// nothing to see here...
}
@Component({
moduleId: module.id,
selector: 'tbody [grid-body]',
templateUrl: './../../html/drive-grid-body.html'
})
export class DriveGridBodyComponent implements IGridBody<Drive>
{
// nothing to see here...
}
@Component({
moduleId: module.id,
selector: '[drive-members-modal]',
templateUrl: './../../html/drive-members-modal.html'
})
export class DriveMembersModalComponent extends GridView<User>
{
@ViewChild(UserGridComponent)
public grid: UserGridComponent;
}
@Component({
moduleId: module.id,
selector: '[user-grid]',
templateUrl: './../../html/grid.html'
})
export class UserGridComponent extends Grid<User>
{
@ViewChild(UserGridHeaderComponent)
public header: UserGridHeaderComponent;
@ViewChild(UserGridBodyComponent)
public body: UserGridBodyComponent;
}
UserGridHeaderComponent
并且UserGridBodyComponent
等同于Drive-
组件。
以下是 html 模板的相关部分:
drive-view.html
<div class="row">
<div class="col-lg-12"
drive-filter-modal
(onFilterApplyButtonEmitter)="onFilterApplyButton()">
</div>
</div>
<div class="row">
<div class="col-lg-12"
drive-members-modal>
</div>
</div>
<div class="row" [hidden]="!grid.body?.items">
<div class="col-lg-12"
drive-grid
(onColumnHeaderToggledEmitter)="onColumnHeaderToggled($event)"
(onDetailsButtonEmitter)="onDetailsButton($event)">
</div>
</div>
<div class="row"
id="row-grid-item-details">
<div class="col-lg-12"
[@detailsSlideUpDown]="itemDetails.fadeInOutStatus">
<item-details (onOpenModalEmitter)="onDriveMembersButton()"></item-details>
</div>
</div>
网格.html
<div class="table-responsive">
<table class="grid table table-hover">
<thead grid-header (onColumnHeaderToggledEmitter)="onColumnHeaderToggled($event)"></thead>
<tbody grid-body (onDetailsButtonEmitter)="onDetailsButton($event)"
[ngClass]="{'fadeIn': body?.items, 'fadeOut': !body?.items}"
class="animated"></tbody>
</table>
</div>
drive-members-modal.html
<div class="modal fade" id="drive-members-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">Members of 'NAME'</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-lg-12"
user-grid
(onColumnHeaderToggledEmitter)="onColumnHeaderToggled($event)"
(onDetailsButtonEmitter)="onDetailsButton($event)">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">
<span class="glyphicon glyphicon-chevron-left"></span> Back
</button>
</div>
</div>
</div>
</div>
</div>
所以我想做的GridView<T>
是DriveMembersModalComponent
重用DriveViewComponent
. 当用户想要查看驱动器的成员时,它应该在弹出的引导模式中呈现类似的网格。
但是DriveViewComponent
'sdriveMembersModal
没有完全初始化。它的
@ViewChild(UserGridComponent)
public grid: UserGridComponent;
保持未定义。似乎 Angular 在模板中找不到匹配的元素。我试过不同的选择器没有效果。我还尝试了将属性添加到元素的@ViewChild(<reference>)
语法。#reference
然而,这给了我一个ElementRef
,我不知道如何处理。它似乎只是一个 DOM 引用,而不是一个角度组件。
编辑:
我从我的应用程序中创建了一个 plunker 示例:https ://embed.plnkr.co/083a5AnkaiCG796adTkR/
请按照以下说明重现错误:
- 打开浏览器的调试模式以查看控制台输出
- 单击“驱动器”选项卡
- 控制台将打印
DriveMembersModalComponent
,它对应于C
上面提到的组件。grid
场undefined
是。打印在DriveViewComponent
's中执行ngAfterViewInit()