2017-06-12 35 views
3

我試圖在其視圖呈現之前從其父級設置子組件屬性。在呈現視圖之前從父級設置子組件屬性

現在我在父組件中使用ViewChildren裝飾器,但在這種情況下太晚了,因爲子視圖必須使用來自父級的數據。

因此,網格類保存網格對象的完整引用,並且我想從網格標題綁定到網格標題項。

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); 
    } 
} 

孩子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子元素必須得到這個引用,所以這是多餘的。

<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

它是如何模樣?我還沒有聽說過如何向其孩子注射家長。 – Twois

+0

不幸的是,父母通過@input裝飾器獲取網格對象,因此當孩子在顯示時注入父對象時,網格屬性爲null。 – Twois

+0

@yurzui你是對的,我發現與componentFactory的其他解決方案,但你的答案更接近這個問題。請發送一封郵件,我會接受。 – Twois

回答

1

由於angular2了基於組件樹的依賴注入系統,我們可以簡單地在子組件注入父組件實例:

網header.component.ts

export class GridHeaderItemComponent implements OnInit { 
    public grid; 
    @Input() name: string = ''; 

    constructor(private parent: GridHeaderComponent) { } 

,然後將parent.grid財產分配給當地grid財產內ngOnInit

網header.component.ts

public ngOnInit() { 
    this.grid = this.parent.grid; 
} 

你也可以看到它在行動Plunker Example

0

有了這個解決方案,您將有機會獲得在ngAfterViewInit數據,但你贏了沒有「依賴性」(parent-> < -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>`, 
}) 
//...