当前位置: 首页 > 知识库问答 >
问题:

模板中异步管道的Observable不适用于单个值

漆雕嘉平
2023-03-14

我有一个组件,它向我的服务请求一个可观察的对象(即,底层http.get返回一个对象)。

在我的模板中,对象(可观察对象)与异步管道一起使用。不幸的是,我得到了一个错误:

无法读取null的属性“lastname”

这件事让我伤了脑筋。类似类型的代码可以正确处理对象列表(与*ngFor结合使用)。

<li>{{(person | async)?.lastname}}</li>

我的服务中的方法:

getPerson(id: string): Observable<Person> {        
   let url = this.personsUrl + "/" + id;
   return this.http.get(url, {headers: new Headers({'Accept':'application/json'})})
              .map(r => r.json())
              .catch(this.handleError); //error handler
}

在我的组件中:

//... imports omitted

@Component({
  moduleId: module.id,
  selector: 'app-details-person',
  templateUrl: 'details-person.component.html',
  styleUrls: ['details-person.component.css'],
})
export class DetailsPersonComponent implements OnInit, OnDestroy 
{
   person: Observable<Person>;
   sub: Subscription;

   constructor(private personService: PersonService, private route: ActivatedRoute) {
   }

  ngOnInit() {
     this.sub = this.route.params.subscribe(params => {
                 let persId = params['id'];
                 this.person = this.personService.getPerson(persId);
                });
  }

  ngOnDestroy(): void {
     this.sub.unsubscribe();
  }
}

显然,observable是/返回管道中的空对象值。我已经检查了我是否真的从我的服务中得到了一个非空的可观察对象,并且我可以确认存在一个从我的服务返回的(底层)对象。

当然,我可以在从服务中检索到可观察性之后在组件中订阅可观察性,但是我真的很想使用异步构造。

顺便说一下,另一个问题:是否已经有了如何处理异步管道中出现的错误的模式?(使用异步管道的缺点......错误会延迟到视图的渲染时间。

共有3个答案

章涵容
2023-03-14

请试着换线

person:Observable< Person>

进入

person:Observable< any>;

如果这不起作用,请打印出这个{{person | async | json},当然,请使用上面的更改,看看您得到了什么。

贺雪松
2023-03-14

您不需要订阅ngOnInit中可观察到的路由数据。

您可以将路由数据与personService observable链接到一个新的observable中,而不是在每次路由数据observable发出时订阅并创建一个全新的observable。这是函数式编程的本质:

函数反应式编程的本质是在声明时完全指定值的动态行为。

记住这一点,您可以在声明时声明关于“人”的所有信息:

person: Observable<Person> = this.route.params.pipe(
  map(params => params.id),
  mergeMap(persId => this.personService.getPerson(persId)),
);

这样做有多种好处:

  • 直到有东西订阅它(比如异步管道),才真正触发可观察对象。这意味着,除非您在模板中使用异步管道,否则它不会向此人发出请求。

话虽如此,异步管道仍然可以默认为null,您可以在模板中使用ngIF来处理它:

 <li *ngIf="(person | async) as person">{{person.lastname}}</li>
白宏义
2023-03-14

第一次呈现视图时,未定义person,因为该组件属性仅在触发route params订阅时异步创建。您首先需要创建一个空的可观察对象。而不是

person:Observable<Person>;

尝试

person = Observable.of<Person>(Person());  // or however you create an empty person object
    // the empty object probably needs a lastname field set to '' or null

我通常通过以下方式处理服务中的错误:

  1. 返回一个空的可观察的
  2. 将错误报告给某个应用范围内的(单例)服务。然后,某个(单例)组件在页面的某个地方显示这些错误(如果合适)。
 类似资料:
  • 问题内容: 在Go模板中,有时将正确的数据传递到正确的模板的方式令我感到尴尬。用流水线参数调用模板看起来就像只用一个参数调用函数。 假设我有一个Gophers网站,有关Gophers。它具有一个主页主模板和一个用于打印Gophers列表的实用程序模板。 http://play.golang.org/p/Jivy_WPh16 输出: 现在,我想在子模板中添加一些上下文:在列表内以不同的方式设置名称“

  • 我最近开始使用空手道。我有一个现有的项目,有步骤与cucumber,现在我正在编写测试使用空手道。由于空手道是建立在cucumber上的,我仍然不能运行我的自定义编写的步骤定义。

  • 我正在使用azure datafactory WebHook获取管道运行的详细信息-使用以下链接按工厂查询。邮递https://management.azure.com/subscriptions/{订阅ID}/resourceGroups/{resourceGroupName}/providers/Microsoft。数据工厂/工厂/{factoryName}/queryPipelineRuns

  • 由于报告缺少react脚本库,在npm init之后运行npm start无法工作。 它在我的Windows 10机器上;我尝试卸载和重新安装节点,但它没有帮助。 我只能通过键入 否则,如果我运行: 我可以看到下面粘贴的错误。 reactapptest@0.1.0启动C:(…)\reactapptest react脚本启动npm错误!文件bash npm ERR!路径bash npm ERR!代码

  • 问题内容: 我有一个Golang模板,定义如下 然后在我的一个文件中使用它: “测试”之后,点是什么意思?Golang模板文档说: 但是我不确定是什么管道。阅读文档没有结果,有人可以再解释一次吗? 另外,为什么我们必须以点开始的值?例如。这也是一种管道吗? 先感谢您! 问题答案: 有2个软件包,和。 它们具有相同的接口,但是该程序包用于生成安全的HTML输出,以防止代码注入,因此应使用该程序包,而

  • 问题内容: 我们有几个Java项目。每个项目都有自己的交付管道。 所有管道都具有以下共同的步骤(简化): 建立项目 发布项目 部署到测试环境 部署到生产环境 项目管道仅在项目特定的属性(例如服务名称或测试和生产环境的IP地址)上有所不同。 问题是:我们如何避免所有项目都有共同之处?Jenkins的“管道作为代码”是否提供类似管道模板的内容? 我可以想象一个模板将在我们的项目管道中节省很多冗余代码/