Angular 为什么来自subscribe函数的回调中的对象一直处于未定义状态?[已解决]

Angular 为什么来自subscribe函数的回调中的对象一直处于未定义状态?[已解决],angular,parent-child,Angular,Parent Child,我正在努力使用Angular中的subscribe函数。我知道这个函数是异步的,因为JavaScript将运行下一段代码,直到检索到REST调用响应为止。 起初我犯了一些错误,总结如下: 使用“+”而不是“,”打印JSON对象 我没有在下一个订阅中添加订阅,因为它是异步工作的 模型与JSON对象不完全相同,属性以大写或小写开头 然后我看到子组件在父组件仍在等待对象检索时被渲染。使用ngOnChanges仍然会给我带来错误,因为在呈现DOM时我需要对象。这是通过在父HTML中使用ngIf解决的

我正在努力使用Angular中的subscribe函数。我知道这个函数是异步的,因为JavaScript将运行下一段代码,直到检索到REST调用响应为止。 起初我犯了一些错误,总结如下:

  • 使用“+”而不是“,”打印JSON对象
  • 我没有在下一个订阅中添加订阅,因为它是异步工作的
  • 模型与JSON对象不完全相同,属性以大写或小写开头
然后我看到子组件在父组件仍在等待对象检索时被渲染。使用ngOnChanges仍然会给我带来错误,因为在呈现DOM时我需要对象。这是通过在父HTML中使用ngIf解决的。见代码:

家长:

export class MachineConfiguratorComponent implements OnInit {

  machine: Machine;

  constructor(
    private configuratorService: ConfiguratorService,
    private route: ActivatedRoute
    ) { }

  ngOnInit() {
    this.route.paramMap.subscribe(param => {
      this.configuratorService.getMachineDetails(param.get('id')).subscribe((res) => {
        this.machine = res;
        console.log("response in parent is: ", res.Description);
      });
    });
  }
}
<div class="container">
<div class="form-row" *ngIf="machine">
    <app-machinedetails-overview [inputMachine]="machine"></app-machinedetails-overview>
</div>
export class MachinedetailsOverviewComponent implements OnInit {

  @Input() inputMachine: Machine;

  constructor() { }

  ngOnInit() { }

  ngOnChanges(){
    console.log("child gives onchanges: ", this.inputMachine)
  }
}
父HTML:

export class MachineConfiguratorComponent implements OnInit {

  machine: Machine;

  constructor(
    private configuratorService: ConfiguratorService,
    private route: ActivatedRoute
    ) { }

  ngOnInit() {
    this.route.paramMap.subscribe(param => {
      this.configuratorService.getMachineDetails(param.get('id')).subscribe((res) => {
        this.machine = res;
        console.log("response in parent is: ", res.Description);
      });
    });
  }
}
<div class="container">
<div class="form-row" *ngIf="machine">
    <app-machinedetails-overview [inputMachine]="machine"></app-machinedetails-overview>
</div>
export class MachinedetailsOverviewComponent implements OnInit {

  @Input() inputMachine: Machine;

  constructor() { }

  ngOnInit() { }

  ngOnChanges(){
    console.log("child gives onchanges: ", this.inputMachine)
  }
}
响应:

有更新的旧问题(代码已删除):

export class MachineConfiguratorComponent implements OnInit {

  machine: Machine;

  constructor(
    private configuratorService: ConfiguratorService,
    private route: ActivatedRoute
    ) { }

  ngOnInit() {
    this.route.paramMap.subscribe(param => {
      this.configuratorService.getMachineDetails(param.get('id')).subscribe((res) => {
        this.machine = res;
        console.log("response in parent is: ", res.Description);
      });
    });
  }
}
<div class="container">
<div class="form-row" *ngIf="machine">
    <app-machinedetails-overview [inputMachine]="machine"></app-machinedetails-overview>
</div>
export class MachinedetailsOverviewComponent implements OnInit {

  @Input() inputMachine: Machine;

  constructor() { }

  ngOnInit() { }

  ngOnChanges(){
    console.log("child gives onchanges: ", this.inputMachine)
  }
}
如果我在subscribe函数后面放置另一行代码来打印机器名,它会给出一个错误,因为机器仍然没有定义。对我来说,这听起来很合乎逻辑,因为还没有从调用中检索到对象。 但是为什么回调中的对象甚至是未定义的呢?我错过什么了吗

我的意思是我可以将机器传递给子组件,并将{{machine?.name}放在HTML中,但是如何确保子组件对于要定义的对象是确定的呢?因为在子组件本身中,我不能使用这个.machine?.name,所以它总是给出一个错误,除非定义了机器。我只看到普通字符串的示例,它们必须将“”放在字符串本身周围,但这是从REST调用检索的对象

更新

以下是回应:

见家长:

export class MachineConfiguratorComponent implements OnInit {

machine: Machine;

constructor(
    private configuratorService: ConfiguratorService,
    private route: ActivatedRoute
    ) { }

  ngOnInit() {
    this.route.paramMap.subscribe(param => {
      this.configuratorService.getMachineDetails(param.get('id')).subscribe((res) => {
        this.machine = res;
        console.log("response in parent is: ", res);
      });
    });
  }
}
请参阅HTML:

    <app-machinedetails-overview [inputMachine]="machine"></app-machinedetails-overview>
这是控制台:
此时,this.route.paramMap和
this.configuratorService.getMachinedDetails将异步运行

在第一个
订阅
中调用
this.configuratorService.getMachinedDetails
,以便
this.configuratorService.getMachinedDetails
可以等待设置
项目ID

大概是这样的:

export class MachineConfiguratorComponent implements OnInit {

  itemId: any;
  machine: Machine;

  constructor(
    private configuratorService: ConfiguratorService,
    private route: ActivatedRoute
  ) {}

  ngOnInit() {
    this.route.paramMap.subscribe(param => {
      this.itemId = param.get('id');
      this.configuratorService.getMachineDetails(this.itemId).subscribe((res) => {
        this.machine = res;
        console.log("response in parent is: " + this.machine.description);
      });
    });
  }
}
<app-machinedetails-overview 
  [inputMachine]="machine">
</app-machinedetails-overview>
更新

这是服务中的restcall方法:

getMachineDetails(machineId:string):可观察{
返回this.httpClient.get(${this.baseUrl+this.machineUrl}/${machineId});
}

以下是回答后的ngOnInit:

ngOnInit() {
this.route.paramMap.subscribe(param => {
  this.configuratorService.getMachineDetails(param.get('id')).subscribe((res) => {
    // this.machine = res;
    console.log("response in parent is: " + res.description);
  });
});
}

更新:

export class MachineConfiguratorComponent implements OnInit {

  machine: Machine;

  constructor(
    private configuratorService: ConfiguratorService,
    private route: ActivatedRoute
    ) { }

  ngOnInit() {
    this.route.paramMap.subscribe(param => {
      this.configuratorService.getMachineDetails(param.get('id')).subscribe((res) => {
        this.machine = res;
        console.log("response in parent is: ", res.Description);
      });
    });
  }
}
<div class="container">
<div class="form-row" *ngIf="machine">
    <app-machinedetails-overview [inputMachine]="machine"></app-machinedetails-overview>
</div>
export class MachinedetailsOverviewComponent implements OnInit {

  @Input() inputMachine: Machine;

  constructor() { }

  ngOnInit() { }

  ngOnChanges(){
    console.log("child gives onchanges: ", this.inputMachine)
  }
}
由于您希望将
机器
用作子组件的
@Input
属性,因此将按如下方式传递它:

export class MachineConfiguratorComponent implements OnInit {

  itemId: any;
  machine: Machine;

  constructor(
    private configuratorService: ConfiguratorService,
    private route: ActivatedRoute
  ) {}

  ngOnInit() {
    this.route.paramMap.subscribe(param => {
      this.itemId = param.get('id');
      this.configuratorService.getMachineDetails(this.itemId).subscribe((res) => {
        this.machine = res;
        console.log("response in parent is: " + this.machine.description);
      });
    });
  }
}
<app-machinedetails-overview 
  [inputMachine]="machine">
</app-machinedetails-overview>

希望解释清楚。

这听起来很有逻辑,我这样做了,但响应仍然给了我未定义的机器。.你知道控制台res值吗?我添加了这个:console.log(“父级中的响应是:+res.description”);但是仍然给出未定义的,并且只有res给出[Object Object]。这确实给了我完整的对象,这可能是因为我的模型属性以小写开头,JSON对象以大写开头吗?我已经更新了它,但它甚至异步调用子对象。我不知道如何让输入等待可能重复的@Salomé。您试图编辑答案以包含更多信息,但不应该。请改为编辑您的问题,并在其末尾添加信息。正确,谢谢!我下次会注意的。以正确的方式提问很难,但仍在学习中。理由如下:)