javascript - Angular 2: egenskap blir undefined


Problemet är att egenskapen som skickas till vybarnet blir undefined:

Föräldrakomponent:

@Component({
    selector: 'app-searchbox',
    template: `
            <app-artifact-list [artifacts]="searchResults"></app-artifact-list>
    `
})
export class SearchboxComponent implements OnInit {

    // explicitly initialize the property 
    // the same effect with constructor initialization
    searchResults: Artifact[] = [new Artifact()];

    constructor(private artifactService: ArtifactService) {
    }

    ngOnInit(): void {
        this.pollService(this.artifactService.findByQuery('guice'));
    }

    private pollService(request: Observable<Artifact[]>) {
        return request.subscribe(this.fillInResults);
    }

    private fillInResults(result: Artifact[]) {
        result.forEach(console.log);
        for (let obj of result) {
            // this.searchResults is undefined! why?
            this.searchResults.push(obj);
        }
    }

}

Barndel:

@Component({
    selector: 'app-artifact-list',
    template: `
            <h1>{{_artifacts | json}}</h1>
    `
})
export class ArtifactListComponent implements OnChanges {

    private _artifacts: Artifact[] = [];

    ngOnChanges(changes: SimpleChanges): void {
        console.log('Property changed');
    }

    @Input()
    set artifacts(artifacts: Artifact[]) {
        console.error('Property changed');
        this._artifacts = artifacts;
    }

}

Under konstruktörens anrop ser jag att egenskapen är korrekt initialiserad men i callbackmetoden blir den undefined.

Är det på något sätt relaterat till this? Kanske refererar this.searchResults till något annat i callbacken?

Svar #1

Efter lite undersökning av this när det används inom ramen för "funktionreferenser" upptäckte jag att this faktiskt refererar till ett annat objekt. Jag älskar JavaScript :)

Så lösningen är:

private pollService(request: Observable<Artifact[]>) {
    return request.subscribe(
        this.fillInResults.bind(this)
    );
}

private fillInResults(result: any) {
    result.forEach(console.log);
    for (let obj of result) {
        this.searchResults.push(obj);
    }
}

Eller att använda fet pil-funktion:

private pollService(request: Observable<Artifact[]>) {
    return request.subscribe(
        result => this.fillInResults(result)
    );
}

private fillInResults(result: any) {
    result.forEach(console.log);
    for (let obj of result) {
        this.searchResults.push(obj);
    }
}

Se denna fråga för en detaljerad förklaring: Angular2-komponentens "this" är odefinierad när man kör callback-funktionen