关键词:
【中文标题】在模板中使用异步管道可观察到的不适用于单个值【英文标题】:Observable with Async Pipe in template is not working for single value 【发布时间】:2017-01-10 20:07:23 【问题描述】:我有一个组件向我的服务请求 Observable 对象(即底层的 http.get 返回一个对象)。
对象(一个可观察对象)在我的模板中与异步管道一起使用。 不幸的是,我收到一个错误:
无法读取 null 的属性“姓氏”
我一直在为这个问题头疼。类似类型的代码可以在对象列表上正常工作(与 *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,并且我可以确认存在从我的服务返回的(基础)对象。
当然,在从服务中检索 Observable 后,我可以在我的组件中订阅 observable,但我真的很想使用异步构造。
顺便说一句,另一个问题:是否已经有关于如何处理异步管道中发生的错误的模式? (使用异步管道的一个缺点......错误会延迟到视图的渲染时间。
【问题讨论】:
这应该可以。请显示返回 observable 的服务代码,以及定义person
的组件代码。或者更好的是,创建一个plunker。
嗨,马克,我已经更新了上面的问题部分。您可以阅读上面的服务片段和组件代码。谢谢。
【参考方案1】:
第一次渲染视图时,person
未定义,因为该组件属性仅在路由参数订阅触发时异步创建。您最初需要创建一个空的 observable。而不是
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
我通常通过
处理服务中的错误-
返回一个空的可观察对象
将错误报告给某些应用程序范围的(单例)服务。然后某些(单一)组件会在页面某处显示这些错误(如果适用)。
【讨论】:
嗨,马克,感谢您的回复。事实上,我同意关于人员和路由参数代码的异步行为。我听从了你的建议,但我仍然看到同样的错误。似乎视图是在定义人员之前呈现的(使用服务调用)。我是否处于错误的生命周期? 如果person = Observable.of<Person>(Person()); is defined before your constructor, it should exist when the view is first rendered. You can test this by commenting out your
this.person = ...`代码。
嗨,马克,(之前)做过,但徒劳无功。这是一个大脑破坏者:-(我开始考虑我是否在库和兼容性方面存在问题。正如你之前所说......这应该有效。直截了当但仍然是一个问题。【参考方案2】:
请尝试换行
person:Observable< Person>
进入
person:Observable< any>;
如果这不起作用,请打印出这个 person | async | json
,当然请使用上面的更改,看看你会得到什么。
【讨论】:
你试过 flatMap 而不是 map 吗?【参考方案3】:您无需订阅ngOnInit
中可观察到的路由数据。
您可以将路由数据与 personService 可观察对象链接在一起,形成一个新的可观察对象,而不是在每次发出路由数据 observable 时都订阅和创建一个全新的 observable。这就是函数式编程的精髓:
函数式反应式编程的本质是指定 声明时值的动态行为。
考虑到这一点,您可以在声明时声明关于“人”的所有内容:
person: Observable<Person> = this.route.params.pipe(
map(params => params.id),
mergeMap(persId => this.personService.getPerson(persId)),
);
这样做有很多好处:
直到有东西订阅它(如异步管道),observable 才会真正触发。这意味着除非您在模板中使用异步管道,否则它不会向该人发出请求。 您不需要处理取消订阅。异步管道将为您完成这项工作。 通过查看代码很容易看出是什么构成了“Person”。这一切都在一个地方定义。 您不需要创建一个空的初始化 observable,它可能不是一个有效的“Person”。话虽如此,异步管道仍然可以默认为 null,您可以在模板中使用 ngIf
处理它:
<li *ngIf="(person | async) as person">person.lastname</li>
【讨论】:
这应该是公认的答案。它避免了创建一个空的人对象,当有正确的方法时,它被用作一种变通方法,并避免了不必要的订阅。【参考方案4】:如果您使用 Subject<T>
observable 而不是 ReplaySubject<T>
或 BehaviorSubject<T>
,则可能会发生这种情况。
Subject<T>
发生的情况是,它只向当时注册的任何听众“广播”一次其值。
因此,如果您在可观察的message: Subject<string>
上调用next('hello word')
,它只能在那个“部分”UI 存在的情况下及时更新UI。
所以在这个例子中消息不会出现 - 除非你调用next
两次!
<div *ngIf="message | async">
here is the message message | async
</div>
最简单的解决方案是使用ReplaySubject<string>(1)
,其中1
是它记住的值的数量(我们这里只需要一个)。
【讨论】:
Ionic 4 Angular模板与异步管道绑定到可观察
】Ionic4Angular模板与异步管道绑定到可观察【英文标题】:Ionic4Angulartemplatebindingwithasyncpipetoobservable【发布时间】:2018-11-1903:23:54【问题描述】:我正在将旧的ionic应用程序从V2移动到V4-alpha,并且无法使用异步管道在模板中绑定到... 查看详情
与模板中的异步管道组合以观察值变化时,管道运算符不起作用
】与模板中的异步管道组合以观察值变化时,管道运算符不起作用【英文标题】:Pipeoperatornotworkingwhencombiningwithasyncpipeintemplateforvaluechangesobservable【发布时间】:2019-10-0514:20:29【问题描述】:我正在尝试捕获用户输入并根据输入... 查看详情
如何使用来自html的异步管道获取可观察对象的嵌套值
】如何使用来自html的异步管道获取可观察对象的嵌套值【英文标题】:Howtogetnestedvaluesofanobservableusingasyncpipefromhtml【发布时间】:2021-03-0222:37:30【问题描述】:我在Angular中有一些html块,我想用一些可观察对象的嵌套值来填写,... 查看详情
Angular/Rxjs 管道异步不适用于 s-s-r?
...无限循环(似乎服务器正在等待解析observable)。我正在使用:@nestjs/ng-universal角9火力基地Rxjs这样一个简单的例子可以工作:<p 查看详情
在单个 MySQL 查询中使用多个临时表(适用于 phpMyAdmin,但不适用于 PHP)
】在单个MySQL查询中使用多个临时表(适用于phpMyAdmin,但不适用于PHP)【英文标题】:UsingmultipletemporarytablesinasingleMySQLquery(worksinphpMyAdmin,butnotPHP)【发布时间】:2014-03-2109:28:36【问题描述】:我想避免使用真实表格作为解决方法... 查看详情
使用表数据中可观察到的剔除值来应用 CSS 类
】使用表数据中可观察到的剔除值来应用CSS类【英文标题】:UsevalueofknockoutobservablewithintabledatatoapplyCSSclass【发布时间】:2021-01-1823:22:06【问题描述】:我正在努力让KOCSSbinding工作。portAvailable是$root.devices中每个设备中存在的可观... 查看详情
可观察管道中的异常被抑制
...servable定期发出值,直到另一个observable发出。所以我可以使用timer和takeUntil来实现这一点。但是然后我想处理每个发出的值并在某些条件变为真时停止(错误)发出。所以我写下一段代码:consttimer,Subject=\ 查看详情
使用http模块时出错-检测到的asp.net设置不适用于集成管理管道模式(代码片段)
启动应用程序时出错。AnASP.NETsettinghasbeendetectedthatdoesnotapplyinIntegratedmanagedpipelinemode.我创建了一个HTTP模块,它从请求头读取信息并将数据写入cookie。这是代码。namespaceMy.WebpublicclassUserIdModule:IHttpModuleprivateHttpApplicat 查看详情
在模板中使用带有异步管道的 Observable 时显示加载
】在模板中使用带有异步管道的Observable时显示加载【英文标题】:DisplayloadingwhileusingObservablewithAsyncpipeintemplate【发布时间】:2017-02-1223:41:30【问题描述】:情况:我正在使用FirebaseObjectObservable来填充我的Ionic2(rc0)模板。模板代码... 查看详情
rxjs-连接并合并两个可观察对象(代码片段)
...jobs$=this.jobSandbox.observeJobsAfterFiltering()我用它作为带有Input管道的Angular组件的async值。我想在单个对象中转换这两个可观察对象并将它们的值“合并”在单个对 查看详情
管道操作符时如何返回可观察到的`forkJoin`
】管道操作符时如何返回可观察到的`forkJoin`【英文标题】:Howtoreturna`forkJoin`observablewhenpipingtheoperators【发布时间】:2018-11-0714:06:25【问题描述】:在我拥有这个运行良好的解析器之前:resolve()returnforkJoin(this.getData1(),this.getData2(),... 查看详情
使用角度异步管道以完全反应式方式刷新数据
...过mergeMap等管道的复杂而复杂的解决方案。我正在组件HTML模板中从命令式HTTP可观察方法(手动订阅)转变为 查看详情
java示例代码_避免在可观察到的事件通知中使用if/else
java示例代码_避免在可观察到的事件通知中使用if/else 查看详情
使用异步管道显示从应用程序状态检索到的 Observable 数据
】使用异步管道显示从应用程序状态检索到的Observable数据【英文标题】:UseasyncpipetoshowObservabledataretrievedfromtheApplicationState【发布时间】:2021-08-2301:17:51【问题描述】:我的代码从ApplicationState获取数据,然后在component.html中显示... 查看详情
如何在角度 http 拦截器中抛出可观察到的错误
】如何在角度http拦截器中抛出可观察到的错误【英文标题】:howtothrowobservableerrorinangularhttpinterceptor【发布时间】:2018-10-1507:57:01【问题描述】:我试图在拦截器中抛出一个可观察到的错误,然后处理这个错误。但我不能。当succ... 查看详情
无法在网络调用中返回可观察到的 customError
...tworkcall【发布时间】:2018-10-1511:16:54【问题描述】:我想使用catchError将我的错误恢复为自定义类型。起初,我希望我的网络层返回Observable,然后在ViewModel中订阅了.OnNext、.OnError、.OnCompleted事件,但我不知道应 查看详情
suppressWarnings() 不适用于管道运算符
...【发布时间】:2018-02-2415:34:04【问题描述】:我正在尝试使用suppressWarnings()函数来抑制警告。令人惊讶的是,它在正常使用时会删除警告,但在使用管道%>%运算符时却无法这样做。这是一些示例代码:library(magrittr)c 查看详情
异步验证器不适用于 Angular 中的模板驱动表单
】异步验证器不适用于Angular中的模板驱动表单【英文标题】:AsyncValidatornotworkingwithTemplatedrivenFormsinAngular【发布时间】:2017-10-1801:31:52【问题描述】:我为我的模板驱动表单创建了一个异步验证器。importDirective,forwardReffrom"@angular... 查看详情