Angular 无法读取属性';已完成';未定义的角2

Angular 无法读取属性';已完成';未定义的角2,angular,Angular,我正在使用@Input(),据我所知,该组件应该能够将绑定到该组件。以下是层次结构: experiment.detail.component.ts import {Component, Input, Output} from '@angular/core'; import {Experiment} from '../../common/experiment.model'; import {ExperimentsService} from "../../common/experiments.se

我正在使用
@Input()
,据我所知,该组件应该能够将
绑定到该组件。以下是层次结构:

experiment.detail.component.ts

import {Component, Input, Output} from '@angular/core';
import {Experiment} from '../../common/experiment.model';
import {ExperimentsService} from "../../common/experiments.service";

@Component({
  selector: 'experiment',
  template: require('./experiment.detail.component.html'),
  styles: [`
    .experiment {
      cursor: pointer;
      outline: 1px lightgray solid;
      padding: 5px;
      margin: 5px;
    }
  `]
})

export class ExperimentDetailComponent {

  experiments: Experiment[];

  constructor(private _experimentsService:ExperimentsService){

  }

  ngOnInit() {
    this.experiments = this._experimentsService.getExperiments();
  }

  @Input() experiment: Experiment;


  doExperiment(): void {
    this.experiment.completed += 1;
  };
}
上面的HTML文件:

<div class="experiment" (click)="doExperiment()">

    <div *ngFor="let experiment of experiments">
        <div *ngIf="experiment">

            {{ experiment.name }}


            <p>
                {{ experiment.description }}
            </p>

            <p>
                <strong>{{experiment.completed}}</strong>
            </p>
        </div>
    </div>
</div>
NGD模块:

import {BrowserModule} from "@angular/platform-browser";
import {NgModule,CUSTOM_ELEMENTS_SCHEMA} from "@angular/core";
import {FormsModule} from "@angular/forms";
import {HttpModule} from "@angular/http";
import {RouterModule} from "@angular/router";
import {HomeComponent} from "./home/home.component";
import {ExperimentsComponent} from "./experiments/experiments.component";
import {AboutComponent} from "./about/about.component";
import {AppComponent} from "./app.component";
import {ExperimentsService} from "./common/experiments.service";
import {StateService} from "./common/state.service";
import {ExperimentDetailComponent} from "./experiments/experiment-details/experiment.detail.component";

    @NgModule({
        declarations: [
            AppComponent,
            AboutComponent,
            HomeComponent,
            ExperimentsComponent,
            ExperimentDetailComponent
        ],
        imports: [
            BrowserModule,
            FormsModule,
            HttpModule,
            RouterModule.forRoot([
                {path: '', redirectTo: '/home', pathMatch: 'full'},
                {path: 'home', component: HomeComponent},
                {path: 'about', component: AboutComponent},
                {path: 'experiments', component: ExperimentsComponent},
                {path: '**', component: HomeComponent}
            ])
        ],
        schemas: [
          CUSTOM_ELEMENTS_SCHEMA
        ],
        providers: [
            ExperimentsService,
            StateService
        ],
        bootstrap: [AppComponent]
    })
    export class AppModule {
    }

Github post

好的,看看你的git项目路线,我可以发现你的
ExperimentComponent
是你的父母,
ExperimentDetail
是孩子。让我们从这开始。从我看到的情况来看,您的代码是反向的,这导致了未定义的错误

在这种情况下,您似乎想要收听child->parent交互。让我们来试一试。您应该使用
@Output()
而不是
@Input()
@Input()
用于父->子交互

因此,您的子组件将发出事件

您的子html:`

<div *ngFor="let experiment of experiments" (click)="doExperiment(experiment)">
            {{ experiment.name }} </div>

你在
实验中有什么?模型
如果你的
@输入
期望一种类型的
实验
为什么你要在这里传递
实验。已完成的
值?它不应该只是一个实验吗?你能发布模块的代码吗?该错误通常发生在未声明子组件以便父组件能够使用它时。@JayChase请参阅更新post@filoxo请参阅更新的帖子和git repoI我正在使用您的第二个解决方案,并获得
self.parentView.context.doExperiment不是一个函数
,但您让我走上了正确的道路。非常感谢。这只是一个学习应用程序,所以这就是为什么有些事情可能没有意义。我在GitHub上更新了项目,现在正在完成它。谢谢你的详细帖子。我给了你两个选项:家长->孩子互动(后者)或孩子->家长互动。如果要使用Input(),则必须更改代码和组件。在您当前的设置中,您需要使用输出,因为您的子组件需要与父组件通信,因此需要输出。现在明白了,这完全有道理。好:D我从答案中删除了整个输入部分,以便您不会感到困惑。我承认我自己也有点不清楚。但现在答案应该很清楚:)
import {BrowserModule} from "@angular/platform-browser";
import {NgModule,CUSTOM_ELEMENTS_SCHEMA} from "@angular/core";
import {FormsModule} from "@angular/forms";
import {HttpModule} from "@angular/http";
import {RouterModule} from "@angular/router";
import {HomeComponent} from "./home/home.component";
import {ExperimentsComponent} from "./experiments/experiments.component";
import {AboutComponent} from "./about/about.component";
import {AppComponent} from "./app.component";
import {ExperimentsService} from "./common/experiments.service";
import {StateService} from "./common/state.service";
import {ExperimentDetailComponent} from "./experiments/experiment-details/experiment.detail.component";

    @NgModule({
        declarations: [
            AppComponent,
            AboutComponent,
            HomeComponent,
            ExperimentsComponent,
            ExperimentDetailComponent
        ],
        imports: [
            BrowserModule,
            FormsModule,
            HttpModule,
            RouterModule.forRoot([
                {path: '', redirectTo: '/home', pathMatch: 'full'},
                {path: 'home', component: HomeComponent},
                {path: 'about', component: AboutComponent},
                {path: 'experiments', component: ExperimentsComponent},
                {path: '**', component: HomeComponent}
            ])
        ],
        schemas: [
          CUSTOM_ELEMENTS_SCHEMA
        ],
        providers: [
            ExperimentsService,
            StateService
        ],
        bootstrap: [AppComponent]
    })
    export class AppModule {
    }
<div *ngFor="let experiment of experiments" (click)="doExperiment(experiment)">
            {{ experiment.name }} </div>
@Output() onIncrement = new EventEmitter<Object>();

doExperiment(experiment) {
    // increments the completed property as you wished
    experiment.completed +=1;
    // here we emit the chosen experiment to the parent
    this.onIncrement.emit(experiment)
};
<experiment (onIncrement)="onIncrement($event)"></experiment>
onIncrement(value) {
    console.log("val: ", value);
    // do whatever you want
}