Angular2:获取异步objectID并传递它

时间:2017-04-19 07:39:06

标签: angular asynchronous

显示需要ID的子视图时,如下所示:

<app-customerview [customerID]="assignedCustomer"></app-customerview>

它按预期工作,但当我尝试直接传递它时:

<app-customerview [customerID]="currentTask.customerId"></app-customerview>

Error: currentTask.customerId

或使用安全访问操作符时:

<app-customerview [customerID]="currentTask?.customerId"></app-customerview>

enter image description here

我认为问题可能是如何检索数据(异步),但我不确定并且不理解为什么第二个选项无效(因为currentTask实际上并未定义)。

检索数据:

getCurrentTask() {
   this._tasksService.getTaskById(this.currentTaskId).subscribe(
      (toReturnTask: Task) => {
         this.currentTask = toReturnTask;
         this.assignedCustomer = "" + this.currentTask.customerId;
       }
   );
}

The child <app-customerview>

3 个答案:

答案 0 :(得分:2)

异步调用尚未完成时,

currentTask未定义,您应该在模板中使用安全访问运算符:{{foo?.bar}}

<app-customerview [customerID]="currentTask?.customerId"></app-customerview>

答案 1 :(得分:1)

如上所述,这是异步的。因此,在渲染子项时,未设置currentTask.customerId。这可以通过 n00dl3 建议的安全导航操作符来解决。

好吧,这不能解决以下问题,在您的孩子中,您的某项功能取决于customerID并且已被解雇OnInit,因此此时customerID将没有价值。因此,请从getCurrentCustomer删除功能ngOnInit

更新:使用主题

您可以使用Official docs中说明的共享服务。但我们也可以这样做,如下:

导入Subject

import { Subject } from 'rxjs/Subject';

在您的孩子中声明Subject

public static fireFunction: Subject<string> = new Subject(); // name however you like

在子构造函数中,只要发出值,就会订阅并触发函数:

CustomerviewComponent.fireFunction.subscribe(res => {
  // apparently the input doesn't have time to be set, therefore passed the value with observable
  // console.log('cont: ', this.content) // will be undefined
  this.getCurrentCustomer(res) // call function with parameter customerID (res)
})

如果在父级中分配了值,则可以将此值发送给子级,然后触发getCurrentCustomer

getCurrentTask() {
   this._tasksService.getTaskById(this.currentTaskId).subscribe(
      (toReturnTask: Task) => {
         this.currentTask = toReturnTask;
         CustomerviewComponent.fireFunction.next(this.currentTask.customerId); // emit to child
       }
   );
}

这意味着没有必要

[customerID]="currentTask?.customerId" 

..在您的子标签中,除非您需要它。该值将在“一段时间”后设置。您可以从标记中删除它,而是将Observable分配给您孩子的本地变量。

DEMO

(使用SubjectViewChild示例,同时检查控制台)

使用VIEWCHILD进行原始发布:

一种解决方案是使用ViewChild并在设置currentTask.customerId后从父级激活该函数。这样我们就可以确保子组件设置为customerID

所以导入......

import {ViewChild} from '@angular/core'

在您的父母中声明:

@ViewChild(CustomerviewComponent) customerviewComp: CustomerviewComponent

现在,您可以从父级触发孩子的功能,在填充getCurrentCustomer后致电currentTask

getCurrentTaskAndSpikeeId() {
   this._tasksService.getTaskById(this.currentTaskId).subscribe(
      (toReturnTask: Task) => {
         this.currentTask = toReturnTask;
         this.customerviewComp.getCurrentCustomer(); // here
       }
   );
}

如上所述,使用模板中的安全导航操作符:

<app-customerview [customerID]="currentTask?.customerId"></app-customerview>

答案 2 :(得分:0)

除了@ViewChildrxjs/Subject之类的 AJT_82 之外,还有其他方法可以做到这一点。有一个函数可以监听您可以在孩子中导入的更改:

import { OnChanges, SimpleChanges } from '@angular/core';

ngOnChanges(changes: SimpleChanges) {
        if (changes['customerId']) {
            this.getCurrentCustomer()();
        }
        console.log(changes);
    }

传递的身份

<app-customerview [customerID]="currentTask?.customerId"></app-customerview>