@Input属性未定义

时间:2017-06-05 16:52:55

标签: angular

我有2个组件,其中一个组件设置另一个组件的输入属性。 问题是输入属性在使用时未定义 第一部分:

import {Component, Input, OnInit} from "@angular/core";
import {Comparison} from "../../../common/domain/comparison";
@Component({
    selector: 'oe-comparison-list',
        template: `<div class="row" *ngFor="let comparisons of comparisonRows">
    <oe-comparison-thumbnail *ngFor="let comparison of comparisons" [comparison]="comparison"></oe-comparison-thumbnail>
</div>`,
    styleUrls: ['./comparison-list.component.css']
})
export class ComparisonListComponent implements OnInit {

    @Input("comparisons")
    private comparisons: Array<Comparison>;
    private comparisonRows: Array<Array<Comparison>>;
    private static readonly COLUMNS: number = 4;

    constructor() {
    }

    ngOnInit(): void {
        this.rows();
    }

    private rows(): void {
        //todo
        this.comparisonRows = [];
        let comparisonArray = [];
        for (let i: number = 0; i < this.comparisons.length; ++i) {
            if (i == 0 || i % ComparisonListComponent.COLUMNS != 0) {
                comparisonArray.push(this.comparisons[i]);
            } else {
                this.comparisonRows.push(comparisonArray);
                comparisonArray = [];
            }
        }
        if (this.comparisons.length < ComparisonListComponent.COLUMNS) {
            this.comparisonRows.push(comparisonArray);
        }
    }
}

第二部分

import {AfterViewChecked, Component, Inject, OnInit} from "@angular/core";
import {Comparison} from "../../../common/domain/comparison";
import {IComparisonService} from "../../../common/services/icomparison.service";
@Component({
    selector: 'oe-comparisons-view',
    template: `<oe-comparison-list [comparisons]="comparisons"></oe-comparison-list>`,
    styleUrls: ['./comparisons-view.component.css']
})
export class ComparisonsViewComponent implements AfterViewChecked, OnInit {

    private comparisons: Array<Comparison>;

    constructor(@Inject('IComparisonService') private comparisonService: IComparisonService) {

    }

    ngOnInit(): void {
        this.comparisonService.fetchComparisons()
            .then(comparisons => this.comparisons = comparisons);
    }
    ngAfterViewChecked(): void {
    }
}

如果我从第二个组件传递来自ngOnInit()的简单数组而没有承诺,一切正常。 我该如何解决这个问题?

ADDED 服务实施

import {Injectable} from '@angular/core';
import {Comparison} from "../../../domain/comparison";
import {IComparisonService} from "../../icomparison.service";

@Injectable()
export class ComparisonServiceMock implements IComparisonService {

    private selectedComparison: Comparison;

    constructor() {
    }


    fetchComparisons(): Promise<Array<Comparison>> {
        let comparison: Array<Comparison> = [
            new Comparison(0, "Toys", "Toys comparison description", new Date(), "toys"),
            new Comparison(1, "Tablets", "Tablets comparison description", new Date(), "tablets"),
            new Comparison(2, "Jogurts", "Jogurts comparison description", new Date(), "jogurts"),
        ];
        return Promise.resolve(comparison);
    }

    selectComparison(comparison: Comparison): void {
        this.selectedComparison = comparison;
    }

    getSelectedComparison(): Comparison {
        return this.selectedComparison;
    }

}

2 个答案:

答案 0 :(得分:2)

请尝试在第二个组件中进行以下更改

import {AfterViewChecked, Component, Inject, OnInit} from "@angular/core";
import {Comparison} from "../../../common/domain/comparison";
import {IComparisonService} from "../../../common/services/icomparison.service";
@Component({
    selector: 'oe-comparisons-view',
    template: `<oe-comparison-list [comparisons]="comparisons" *ngIf="!isLoading"></oe-comparison-list>`,
    styleUrls: ['./comparisons-view.component.css']
})
export class ComparisonsViewComponent implements AfterViewChecked, OnInit {

    private comparisons: Array<Comparison>;
    private isLoading: boolean = true;

    constructor(@Inject('IComparisonService') private comparisonService: IComparisonService) {

    }

    ngOnInit(): void {
        this.comparisonService.fetchComparisons()
            .then(comparisons => {
              this.comparisons = comparisons;
              this.isLoading = false;
            });
    }
    ngAfterViewChecked(): void {
    }
}

您可以阅读此3 Ways to Pass Async Data to Angular 2+ Child Components以了解有关此问题的更多信息。

答案 1 :(得分:1)

我认为您的输入变量声明存在问题,请尝试更改:

@Input("comparisons")
private comparisons: Array<Comparison>;

@Input("comparisons") comparisons: Array<Comparison>;

或等效地

@Input() comparisons: Array<Comparison>;

<强>更新 您可能还需要将comparisons中的ComparisonsViewComponent属性设置为public

最近的Angular版本不支持在模板代码中访问private成员。见https://github.com/angular/angular-cli/issues/5620

相关问题