angular - 更改后文本框未立即更新
问题描述
我是 Angular 的绝对初学者,目前正在开发一个通过 http 访问服务的项目。用户可以将文件发送到服务(使用 HttpClient)。进程更新(使用 SignalR)应显示在文本区域中。更新正确地进入我的组件。控制台日志立即显示。但是 textarea 仅在一切完成后才更新(过程完成后,从服务中获取结果)。
我的组件 HTML 以显示流程更新:
<textarea name="status" id="status"
[ngModel]="status | async" // binding to property of StatusComponent
#name="ngModel"
disabled>
</textarea>
我的组件 TS 以显示流程更新:
export class StatusComponent implements OnInit {
public status: Observable<string> = new Observable<string>(); // binding to view
private states: string[] = []; // store states as list
constructor(private protocol: ProtocolService) { }
ngOnInit(): void {
this.protocol.getStatus()
.pipe(share())
.subscribe(state => {
console.log("update state: " + state); // is shown in time
this.states.push(state);
this.status = of(this.states.join("\n")); // is shown when all processes are finished
}
);
}
}
存储状态的我的协议服务:
@Injectable({providedIn: 'root'})
export class ProtocolService {
private status: Subject<string> = new Subject<string>();
constructor() { }
public getStatus(): Observable<string> {
return this.status.asObservable()
.pipe(share());
}
public setStatus(state: string){
this.status.next(state);
this.addToProtocol(state);
}
}
在绑定到我的输入表单的另一个组件中,请求被发送到 http 服务并处理来自 signalr 的回调。它还在 ProtocolService 中设置状态。这里只是 TS 的摘录:
export class ProcessComponent implements OnInit {
constructor(
private service: ProcessService,
private broadcast: SignalRService,
private protocol: ProtocolService
)
}
public connect() {
this.broadcast.startConnection(this.url);
this.broadcast.addDocumentStatusListener(this.onDocumentStatusUpdate.bind(this)); // get updates from signalr
}
public process() {
this.service.process(this.url, this.selectedProject, this.file)
.subscribe((res) => { });
}
private onDocumentStatusUpdate(dto: DocumentStateDto) {
const entry: string = ClassificationState[state];
this.protocol.setStatus(entry);
}
}
我的流程服务:
@Injectable({providedIn: 'root'})
export class ProcessService {
public process(url:string, project: string, file: File): Observable<ProcessDto> {
const formData: FormData = new FormData();
formData.append(file.name, file, file.name);
const request:string = this.buildRequest(url, this.uploadRequest);
var result = this.client.post<any>(request, formData)
.pipe(
share(),
catchError(this.handleError("process", null)));
return result;
}
}
我的 SignalR 服务:
@Injectable({providedIn: 'root'})
export class SignalRService {
private hubConnection?: signalR.HubConnection;
public startConnection(url: string) {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl(url)
.withAutomaticReconnect()
.build();
this.hubConnection?.start()
.catch((err) => console.log('Error while starting connection: ' + err));
}
public addDocumentStatusListener(DocumentStatusCallback: Function) {
this.addBroadcastDocumentStatusListener(DocumentStatusCallback);
}
private addBroadcastDocumentStatusListener(callback: Function) {
this.hubConnection?.off('BroadcastDocumentStatus');
this.hubConnection?.on('BroadcastDocumentStatus', (guid, processStatus, documentStatus) => {
var dto: DocumentStateDto = {Guid: guid, ProcessState: processStatus, DocumentState: documentStatus};
callback(dto);
});
}
我想知道为什么我的控制台日志会立即输出,而 textarea 最终只会更新。我在firefox和chrome上测试过。此外,我测试了使用字符串变量而不是 Observable 并使用输入(类型文本)而不是 textarea,但行为始终相同。我在一个小项目中隔离了这个问题。当我使用超时回调更新文本区域时,文本会立即显示。当 SignalR 发挥作用时,文本框输出会延迟。我是否以不好的方式使用 SignalR,以至于我阻止了文本框输出?
如果您需要更多信息或代码,请不要犹豫询问。我感谢任何有助于更好地理解这个问题的帮助。
最好的,BerkelBits
解决方案
推荐阅读
- angular - Angular中的等高线图不起作用
- swiftui - 如何在 SwiftUI 中使用来自其他结构/视图的函数?
- python - 急切执行函数的输入不能是 Keras 符号张量、自定义损失函数、Tensorflow 2、梯度磁带
- laravel-8 - 检索 id 并选中相关框
- azure - Azure AD 身份验证错误:IDX10214:观众验证失败
- python - 如何在 Oracle SQL 或 Python 中逐步取平均值
- javascript - Django:如何在不更改 url 的情况下单击按钮打开一个小窗口
- json - Xcode compactMap返回可解码的空数组
- scikit-learn - x数据缩放下的KernelRidge参数
- javascript - 悬停效果的图像不会保持可见