我正在尝试使用Observables测试没有后端api的前端代码。 在组件的模板中,我有一个文本区域。最终,我需要使用http.post将textarea内容发送到后端api,并接收对该内容的验证。
在我的component.ts的构造函数中,我定义了一个observable,它做了一些非常基本的检查,并在2000ms超时后创建了模拟结果(例如http.post/http.get):
private obsVal: Observable < any >;
private obsChange: Observable < any >;
constructor() {
this.obsVal = Observable.create(observer => {
setTimeout(() => {
let errorInfo = {};
let val = Math.floor(Math.random() * 10) + 1;
if (val < 6) {
errorInfo['error'] = true;
errorInfo['info'] = "Error! Unknown expression encountered.";
} else {
errorInfo['error'] = false;
}
observer.next(errorInfo);
}, 1000)
});
在textarea内部进行任何更改时,都会调用以下函数(创建另一个可观察的对象并进行订阅):
textarea.on('change', () => {
this.obsChange = Observable.create(observer => {
observer.next("some text inside textarea");
})
this.obsChange.pipe(
debounceTime(400),
distinctUntilChanged(),
switchMap((text) => {
return this.obsVal
})
)
.subscribe(errorResp => {
this.addPanel(errorResp)
});
})
addPanel
在文档中添加DOM元素以显示响应。
我使用了debounceTime,distinctUntilChanged和switchMap,因此,如果用户连续键入,则仅呈现最新的请求。 但是,似乎这些管道中的运算符无法正常工作,因为我一次又一次收到所有响应。
我肯定在这里犯了一些重大的概念错误。有人可以指出吗?
注意:textarea元素是在组件内部动态创建的,因此我无法访问此(change)="doSomething()"
事件。
更新: 我试图像这样post更新代码。
我没有在每次更改时都通过订阅,而是创建了一个主题,并在ngOnInit()中将其称为订阅:
ngOnInit() {
this.subscription = this.obsChange.pipe( //obsChange is the subject
debounceTime(400),
distinctUntilChanged(),
switchMap((text) => {
return this.obsVal
})
)
.subscribe(errorResp => {
this.addPanel(errorResp)
});
}
在更改事件上,而不是创建一个新的obsChange observable,我将next()调用到现有的obsChange:
textarea.on('change', () => {
this.obsChange.next("some text");
})
这是第一次工作,但是在进行进一步更改时会调用next(),但不会触发ngOnInit()中的obsChange。