javascript - 在呈现 View 之前从父级设置子组件属性

标签 javascript angular typescript

我试图在其 View 呈现之前设置其父组件的子组件属性。

现在我在父组件中使用 ViewChildren 装饰器,但在这种情况下为时已晚,因为 subview 必须使用来自父组件的数据。

所以网格类持有网格对象的完整引用,我想从 grid-header 绑定(bind)到 grid-header-item。

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

子组件 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>

最佳答案

由于 angular2 有基于组件树的依赖注入(inject)系统,我们可以简单地在子组件中注入(inject)父组件实例:

grid-header.component.ts

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

    constructor(private parent: GridHeaderComponent) { }

然后将 parent.grid 属性分配给 ngOnInit 中的本地 grid 属性

grid-header.component.ts

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

您还可以在 Plunker Example 中看到它的实际效果

关于javascript - 在呈现 View 之前从父级设置子组件属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44503250/

相关文章:

javascript - karma 测试 : the synthetic property @transitionMessages. 请在您的申请中包含 "BrowserAnimationsModule"或 "NoopAnimationsModule"

javascript - 当元素进入视口(viewport)时触发 anime.js 动画

javascript - JQuery - $ 未定义

javascript - Angular Material 垫卡宽度作为内部文本宽度

javascript - 类型 '() => Promise<AxiosResponse<any>>'不能用作索引类型[ReactJs]

typescript - 如何递归地从类型中省略键

javascript - 如何在 Angular 中将 ng-attr-id 转换为 id

Javascript:两个不同的对象共享一个数组属性?

Angular Universal - 如何手动触发从服务器端到客户端 View 的状态更改?

winjs - 集成 WinJS 和 Angular2