Angular点击后数据不刷新:停用行需多次点击才生效
Hey there, let's break down why your deactivate button sometimes needs two clicks to refresh the table—this is a super common async timing issue, and it's easy to fix once you spot it.
The Root Cause
Looking at your OnDeactivate method in the component:
OnDeactivate(id: string) { this._AllMachines.DeActivateMachine(id); this.LoadData(); }
Here's the problem: DeActivateMachine fires an asynchronous HTTP POST request to your MVC backend, but you're calling LoadData() immediately after—before the deactivate request has actually finished updating the database.
So you end up in a race condition:
- If the
LoadData()request finishes first, you're fetching the old, still-active data (hence the table doesn't update) - If the deactivate request finishes first,
LoadData()gets the updated data (so it works on the first click)
That's why it's inconsistent! Your backend breakpoint shows LoadData() is always called, but sometimes it's pulling data before the deactivate change is saved.
Fix Step 1: Update the Service to Return an Observable
First, let's fix your AllMachines service's DeActivateMachine method. Right now, it's probably firing the request but not letting the component know when it's done. Let's make it return an Observable so the component can wait for completion:
DeActivateMachine(id: string) { let body = JSON.stringify({ MachineId: id }); let headers = new Headers({ 'content-type': 'application/json' }); let options = new RequestOptions({ headers: headers }); // Return the Observable instead of subscribing here return this.http.post(this.DeActivateUrl, body, options) .map((response: Response) => response.json()) .catch(err => { console.error('Deactivation failed:', err.json().message); return Observable.throw(err); }); }
By returning the Observable, we let the component control when to react to the request's success/failure.
Fix Step 2: Wait for Deactivation to Complete Before Loading Data
Now update your component's OnDeactivate method to only call LoadData() after the deactivate request successfully finishes:
OnDeactivate(id: string) { this._AllMachines.DeActivateMachine(id) .subscribe( () => { // Only reload data once deactivation is confirmed successful this.LoadData(); }, (error) => { // Add user feedback here if deactivation fails alert(`Failed to deactivate machine: ${error.message}`); } ); }
This ensures that you're only fetching data once the backend has actually updated the machine's status—no more race conditions, no more double-clicking.
Bonus Optimizations
- Add a loading state: Disable the deactivate button while the request is in flight to prevent accidental double-clicks
- Improve error handling: Replace the alert with a nicer UI notification (like a toast message)
- Verify your backend: Make sure your MVC
DeActivateMachineaction is correctly saving the status change and returning a 200 OK response when successful
内容的提问来源于stack exchange,提问作者user9120125

