gpt4 book ai didi

具有原始值的 Angular onpush 变化检测策略

转载 作者:搜寻专家 更新时间:2023-10-30 21:18:59 24 4
gpt4 key购买 nike

可能是我误解了 Angular changeDetection 策略。

这里是描述:

  • 我有 2 个同级组件(​​S1 和 S2)
  • 将这两个组件都视为显示一些图形数据的小部件
  • 加载时,我想一开始就在两个组件上显示数据。 (为此我使用行为主题)
  • 我想从 S1 通知 S2 触发一个 http 服务调用。 (我在 S1 中使用了行为主题并在单击按钮时调用 .next。我在 S2 中订阅了相同的可观察对象以获取数据)
  • 我的 S2 组件注册了 onPush 变更检测策略。
  • 我正在使用 loading 文本,而 http 服务调用正在进行中,然后在完成后使用 ngIf 使用原始变量 this.loading=true/删除文本假的

现在我的问题是,当应用程序最初加载时,我可以在 S2 小部件上看到 loading... 文本,然后数据被填充。

但是当我点击 S1 中的 notify sibling 按钮时,它确实触发了服务调用,但是当 http 正在处理时我看不到 loading...文本。

这是 S1 的代码:

import { Component, OnInit } from '@angular/core';
import { MessagingService } from '../messaging.service';

@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {

constructor(private _sendMessage: MessagingService) { }

ngOnInit() {
}
notifyChild() {
this._sendMessage.notifySibling();
}
}

这里是S2的代码:

import { Component, OnInit,ChangeDetectionStrategy ,ChangeDetectorRef} from '@angular/core';
import { MessagingService } from '../messaging.service';
import { switchMap, takeUntil, delay } from 'rxjs/operators';
import { of } from 'rxjs';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChildComponent implements OnInit {
public loading = true;
public myData: any;
constructor(private _receiveMessage: MessagingService,private cd: ChangeDetectorRef) { }

ngOnInit() {
this._receiveMessage.registerNotification().pipe(
switchMap(res => {
this.loading = true;
/** Simulate http call below */
return of([res.data]).pipe(
delay(5000)
)
})
).subscribe(response => {
this.myData = response;
this.loading = false;
this.cd.markForCheck();
})
}

}

注意:我在订阅中添加了this.cd.markForCheck();。如果我对此发表评论,就像我只看到 loading... 而没有显示任何数据

消息服务:

import { Injectable } from '@angular/core';
import { Subject, BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class MessagingService {
public _notify = new BehaviorSubject({ data: "initial Call" });
public notify = this._notify.asObservable();
constructor() { }

notifySibling() {
this._notify.next({ data: 'call from sibling' });
}
registerNotification() {
return this.notify;
}

}

完整的工作示例发布在 stackblitz

最佳答案

OnPush 策略仅在 @Input 属性更改时运行检查如果你想在异步上下文中运行它,你必须调用 this.cd.markForCheck( ) 自己在请求前和请求后。

ngOnInit() {
this._receiveMessage.registerNotification().pipe(
switchMap(res => {
this.loading = true;
/** note this */
this.cd.markForCheck();
return of([res.data]).pipe(
delay(1000)
)
})
).subscribe(response => {
this.myData = response;
this.loading = false;
this.cd.markForCheck();
})
}

https://stackblitz.com/edit/angular-pmvmgz

英语不是我的母语:(

关于具有原始值的 Angular onpush 变化检测策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53476204/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com