Pic*_*cci 4 rxjs angular angular-test
我有一个简单的组件,它使用一个返回 Observable 的服务。此类 Observable 用于通过 控制 html 元素的创建*ngIf。
这里的代码
@Component({
selector: 'hello',
template: `<h1 *ngIf="stuff$ | async as obj">Hello {{obj.name}}!</h1>`,
styles: [`h1 { font-family: Lato; }`],
})
export class HelloComponent implements AfterViewInit {
constructor(
private myService: MyService,
) {}
stuff$;
ngAfterViewInit() {
this.stuff$ = this.myService.getStuff();
}
}
@Injectable({
providedIn: 'root'
})
export class MyService {
getStuff() {
const stuff = {name: 'I am an object'};
return of(stuff).pipe(delay(100));
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,getStuff()返回和 Observable 带有 adelay并且一切都按预期工作。
现在我删除了delay,我在控制台上收到以下错误
错误:ExpressionChangedAfterItHasBeenCheckedError:检查后表达式已更改。以前的值:'ngIf: null'。当前值:'ngIf: [object Object]'。
这是不可避免的吗?有没有办法避免这个错误?这个小例子复制了一个真实世界的例子,其中MyService查询后端,所以延迟。
这对我来说很重要,因为我希望能够以模拟真实后端的同步方式运行测试,并且当我尝试这种方法时,我得到了相同的结果。
该错误基本上是说一个更改触发了另一个更改。它delay(100)之所以发生,是因为 RxJS 是严格顺序的,并且订阅是同步发生的。如果您使用delay(100)(即使您只使用delay(0)它,它也会使发射异步,因此它发生在另一个帧中并被另一个更改检测周期捕获。
避免这种情况的一个非常简单的方法是使用setTimeout()或包装对变量的赋值NgZone.run()。
或者更多的“接收方式”正在使用subscribeOn(async)运算符:
import { asyncScheduler } from 'rxjs';
import { observeOn } from 'rxjs/operators';
...
return of(stuff).pipe(
observeOn(asyncScheduler)
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2495 次 |
| 最近记录: |