我正在尝试在其视图呈现之前从其父级设置子组件属性。
现在我在父组件中使用ViewChildren装饰器,但在这种情况下为时已晚,因为子视图必须使用来自父组件的数据。
所以网格类保存了网格对象的完整引用,我想从grid-header绑定到grid-header-item。
Root html:
<grid-header [grid]="grid" [ngClass.xs]="{'search-open': grid.searchToggle, 'mobile-header': true}">
<grid-header-item fxFlex="75px" name="Level"></grid-header-item>
<grid-header-item fxFlex name="Type"></grid-header-item>
<grid-header-item fxFlex name="Stats"></grid-header-item>
</grid-header>
父组件:
import { Component, ViewChildren, forwardRef, Input, OnInit, AfterViewInit, OnDestroy } from '@angular/core';
import {
StorageService,
} from '../../_shared';
import {
GridHeaderItemComponent,
} from './';
@Component({
selector: 'grid-header',
templateUrl: './grid-header.component.html',
styleUrls: ['./grid-header.component.scss'],
host: {'fxLayout': 'row'}
})
export class GridHeaderComponent implements OnInit, AfterViewInit {
constructor(storage: StorageService) {}
@Input() grid = null;
@ViewChildren(forwardRef(() => GridHeaderItemComponent)) private headerItem;
public ngOnInit() {
}
public ngAfterViewInit() {
console.log(this.headerItem);
setTimeout(() => {
this.headerItem.grid = this.grid;
}, 0);
}
}
子组件:
import { Component, HostBinding, Input, OnInit, OnDestroy } from '@angular/core';
import {
StorageService,
} from '../../_shared';
@Component({
selector: 'grid-header-item',
templateUrl: './grid-header-item.component.html',
styleUrls: ['./grid-header-item.component.scss'],
host: {
}
})
export class GridHeaderItemComponent implements OnInit {
public grid;
constructor(storage: StorageService) {}
@Input() name: string = '';
public ngOnInit() {
console.log(this.name);
}
public ngOnDestroy() {
// this.storage.unsubscribeAll(this.class);
}
}
child componetn html:
<span class="item" (click)="grid.onSortBy(name);">
{{name}} <span *ngIf="grid.sort == name" class="fa" [ngClass]="grid.getDirection(name)"></span>
</span>
我知道,如果我将[grid] =“grid”添加到grid-header-item元素它可以工作,但我认为这是一个开销,因为所有的grid-header子节点都必须得到这个引用所以这是多余的
<grid-header [grid]="grid" [ngClass.xs]="{'search-open': grid.searchToggle, 'mobile-header': true}">
<grid-header-item fxFlex="75px" [grid]="grid" name="Level"></grid-header-item>
<grid-header-item fxFlex [grid]="grid" name="Type"></grid-header-item>
<grid-header-item fxFlex [grid]="grid" name="Stats"></grid-header-item>
</grid-header>
答案 0 :(得分:1)
由于angular2具有基于组件树的依赖注入系统,我们可以简单地在子组件中注入父组件实例:
<强>网格header.component.ts 强>
export class GridHeaderItemComponent implements OnInit {
public grid;
@Input() name: string = '';
constructor(private parent: GridHeaderComponent) { }
然后将parent.grid
属性分配给ngOnInit中的本地grid
属性
<强>网格header.component.ts 强>
public ngOnInit() {
this.grid = this.parent.grid;
}
您还可以在 Plunker Example
中查看它答案 1 :(得分:0)
使用此解决方案,您可以访问ngAfterViewInit中的数据,但您不会拥有“circural dependecy”(parent-&gt;&lt; -child)。如果您需要更详细的通信,请尝试使用事件或共享服务。
<强> gridHeader.component.ts 强>
@Component({
selector: 'grid-header-item',
template: `
<span class="item" (click)="grid.onSortBy(name);">
{{name}} <span *ngIf="grid.sort == name">Sortby</span>
</span>
`
})
export class GridHeaderItemComponent{
@Input() name: string = '';
public grid:any = {};
}
@Component({
selector: 'grid-header',
template: `
<grid-header-item fxFlex="75px" name="Level"></grid-header-item><br/>
<grid-header-item fxFlex name="Type"></grid-header-item><br/>
<grid-header-item fxFlex name="Stats"></grid-header-item>`
})
export class GridHeaderComponent implements AfterViewInit{
@ViewChildren(GridHeaderItemComponent) private headers:Array<headerItem>;
@Input() grid = {};
ngAfterViewInit() {
this.headers.forEach(h=>{//it can be a QueryList too
h.grid=this.grid;
});
}}
在网格的包装器组件中,你有这样的东西:
@Component({
selector: 'my-app',
template: `<grid-header [grid]="grid"></grid-header>`,
})
//...