Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular OnInit和异步管道之间的计时问题_Angular_Rxjs_Async Pipe - Fatal编程技术网

Angular OnInit和异步管道之间的计时问题

Angular OnInit和异步管道之间的计时问题,angular,rxjs,async-pipe,Angular,Rxjs,Async Pipe,我对async-管道与Observable组合有问题,后者在OnInit中获取它的第一个值。必须是关于OnInit发生的时间点,以及模板被呈现,从而可观察的被订阅的时间点的时间问题 考虑这一部分: 导出类AppComponent实现OnInit{ 主题A$:主题; 主题B$:主题; 建造师( 受保护的http:HttpClient ) { } 恩戈尼尼特(){ this.subjectA$=新主题(); this.subjectA$.next({name:“A”}); this.subjectB

我对
async
-管道与
Observable
组合有问题,后者在
OnInit
中获取它的第一个值。必须是关于
OnInit
发生的时间点,以及模板被呈现,从而
可观察的
被订阅的时间点的时间问题

考虑这一部分:

导出类AppComponent实现OnInit{
主题A$:主题;
主题B$:主题;
建造师(
受保护的http:HttpClient
) {
}
恩戈尼尼特(){
this.subjectA$=新主题();
this.subjectA$.next({name:“A”});
this.subjectB$=新主题();
设置超时(()=>{
this.subjectB$.next({name:“B”});
}, 0);
}
}
以及模板:


subjectA:{{subjectA.name}

无主语

subjectB:{{subjectB.name}

无主题B

这导致

no subjectA

subjectB: B 
这意味着:即使
subjectA$
onInit
中获得了一个值,视图也不会更新。如果我在
setTimeout
中创建第一个值,正如您在
subjectB$
中看到的那样,它会工作,我会看到值。虽然这是一个解决方案,但我想知道为什么会发生这种情况,还有更好的解决方案吗?

我已经找到的一个解决方案是使用
BehaviorSubject
而不是提供第一个值作为初始值:


this.subjectC$=新的行为主体({name:“C”});
使用subjectC的类似模板引导到
subjectC:C

我真正的可观察对象根本不是
主题
,而是不同内容的
组合相关测试
-调用的结果,从中只有一个是
主题
(不幸的是,因为它使用的是
@Input()
-注释中的值),并使用
OnInit
中的
next
手动按下,如示例所示。其余部分来自
http
等。很可能我可以将组合结果包装成
behavior subject
,但对我来说,它看起来丑陋而危险,因此比
setTimeout
方法更糟糕。但我打赌有人能帮我找到一个真正有用的解决办法。 此外,我更愿意避免
行为主体
,以防止开发人员尝试使用
getValue


一个快速修复方法是与缓冲区1一起使用,而不是与
行为主体一起使用。您不必提供默认值,它既没有
getValue()
函数,也没有
value
getter。但它缓冲(或保存)最后发出的值,并在新订阅时立即发出

试试下面的方法

ngOnInit(){
this.subjectA$=新的ReplaySubject(1);
this.subjectA$.next({name:“A”});
this.subjectB$=新的ReplaySubject(1);
this.subjectB$.next({name:“B”});
this.subjectC$=CombineTest([this.subjectA$,this.subjectB$]).pipe(
映射((things:[{name:string},{name:string}]):{name:string}=>{
return{name:things.map(thing=>thing.name).join(“|”)}
})
);
}

我已经修改了您的。

一个快速修复方法是使用buffer 1,而不是
BehaviorSubject
。您不必提供默认值,它既没有
getValue()
函数,也没有
value
getter。但它缓冲(或保存)最后发出的值,并在新订阅时立即发出

试试下面的方法

ngOnInit(){
this.subjectA$=新的ReplaySubject(1);
this.subjectA$.next({name:“A”});
this.subjectB$=新的ReplaySubject(1);
this.subjectB$.next({name:“B”});
this.subjectC$=CombineTest([this.subjectA$,this.subjectB$]).pipe(
映射((things:[{name:string},{name:string}]):{name:string}=>{
return{name:things.map(thing=>thing.name).join(“|”)}
})
);
}

我已经修改了你的。

在我发表评论之后,我真的忍不住想一定有更好的方法——最后想到了一些有效的方法

我只是稍微修改了一下你的stackblitz

private valueA = "A";
private valueB = "B";

subjectA$ = of({ name: this.valueA });
subjectB$ = of({ name: this.valueB });
subjectC$ = combineLatest([this.subjectA$, this.subjectB$])
          .pipe(
            map((things: [{name:string}, {name:string}]): {name:string} => {return {name: things.map(x => x.name).join('|')}})
          );

这样,我们甚至可以放弃
ngOnInit
hook,一切都应该在它上面运行

在我发表评论之后,我真的忍不住想一定有更好的办法——最后想到了一些行之有效的办法

我只是稍微修改了一下你的stackblitz

private valueA = "A";
private valueB = "B";

subjectA$ = of({ name: this.valueA });
subjectB$ = of({ name: this.valueB });
subjectC$ = combineLatest([this.subjectA$, this.subjectB$])
          .pipe(
            map((things: [{name:string}, {name:string}]): {name:string} => {return {name: things.map(x => x.name).join('|')}})
          );

这样,我们甚至可以放弃
ngOnInit
hook,一切都应该在它上面运行

最近有一个类似的问题(特别是将@输入转换为可观察的),我可以通过使用
shareReplay(1)
(或者使用缓冲区为1的
ReplaySubject
)来解决对于可观察对象-do.next inside
ngOnInit
的问题似乎是它在模板实际订阅可观察对象之前先运行。将内容移动到ngAfterViewInit(或ngAfterContentInit)并不能真正解决问题,因为更改检测会抱怨。因此,我剩下的就是重放最后一个值,将其存储在
行为子对象中,或者也使用
设置超时值。。。互联网上怎么会充斥着使用
async
而不是手动订阅的建议,但却没有一个合适的解决方案呢?最近有一个类似的问题(特别是将@Input转换为observatable),我可以通过使用
shareReplay(1)
(或者使用缓冲区为1的
ReplaySubject
)来解决对于可观察对象-do.next inside
ngOnInit
的问题似乎是它在模板实际订阅可观察对象之前先运行。将内容移动到视图中