路由器导航加载程序延迟问题-如何手动调用

时间:2019-03-06 18:16:39

标签: angular

在单击网页上的routerLink时,如果loading = true,则显示加载程序。 它可以在任何地方工作,但在下面的组件中,由于{{1} 从后端获取动态ID需要半秒,而只有在获取ID之后才激活路由。因此延迟。 我该如何解决? 有没有一种方法可以在this.router.navigate(['/dashboard/invoice',res.body.data.id]);函数运行时立即调用NavigationStart事件,因此它没有响应延迟。

html

createInvoice

<button (click)="createInvoice(details)" class="select-plan">Choose Plan</button>

应用组件

 createInvoice(plan: any){
        this.auth.createInvoice(plan).subscribe((res:any)=>{
          if(res.status==200) {
            if(res.body.data.id){
            this.router.navigate(['/dashboard/invoice',res.body.data.id]); 
            } 
          }
        }, (err)=>{
        })
      }

1 个答案:

答案 0 :(得分:0)

据我所知这是不可能的。要解决此问题,我建议将您的加载状态与路由器状态解耦。当前实现假定负载仅响应路由更改而更新,而实际上可以通过多种方式(在此示例中为API请求)进行更改。
创建单独的LoadingService来管理此状态将使您可以从应用程序中的任何位置更新状态。这还允许向应用程序中任何位置的消费者通知加载事件。看起来像这样:

@Injectable({providedIn: 'root'})
export class LoadingService {

  // Create subject with initial state of true (assumed from default value of AppComponent.loading)
  private loadingSubject = new BehaviorSubject<boolean>(true);

  // Expose the subject as an Observable, allowing consumers to subscribe to be notified of changes
  loading$: Observable<boolean> = this.loadingSubject.asObservable();

  setLoading(loading: boolean) {
    // Update the loading subject
    this.loadingSubject.next(loading);
  }

}

以上服务使用BehaviorSubject来跟踪当前加载状态。它将主题公开为可观察对象,允许消费者订阅更改。

在路由更改时,与其更新局部变量,不如更新注入的服务:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  constructor(private router: Router, private loadingService: LoadingService) { 
    this.router.events.subscribe((routerEvent: Event)=>{
      if(routerEvent instanceof NavigationStart) {
        this.loadingService.setLoading(true);
      }
      if(routerEvent instanceof NavigationEnd || 
         routerEvent instanceof NavigationCancel || 
         routerEvent instanceof NavigationError){
         this.loadingService.setLoading(false);
      }
    });
  }
}

现在状态是在服务中管理的,我们不再需要仅依靠路由更改来更新加载状态。您可以像在上面的AppComponent中一样在任何地方注入加载服务并更新状态:

createInvoice(plan: any){
        this.loadingService.setLoading(true); // Set the loading state directly

        this.auth.createInvoice(plan).subscribe((res:any)=>{
          if(res.status==200) {
            if(res.body.data.id){
            this.router.navigate(['/dashboard/invoice',res.body.data.id]); 
            } 
          }
        }, (err)=>{
        })
      }