ChangeDetector Ref in Angular 4中的错误

ChangeDetector Ref in Angular 4中的错误

问题描述:

我和其他人有类似的错误。但我真的可以解决它。错误是ERROR Error: ViewDestroyedError: Attempt to use a destroyed view: detectChanges.我已经查看其他人的类似问题,但是我看不到我的应用程序的良好答案。我想检测更改是否有5秒钟的新数据。我希望它出现在我的浏览器中。所以我用改变了Detector ref,但是它给出了错误。ChangeDetector Ref in Angular 4中的错误

export class UsersListComponent implements OnInit { 
    closeResult: string; 
    users: any; 
    subscription: Subscription; 
    modalRef: NgbModalRef; 
    intervalHolder: any; 
    constructor(private modalService: NgbModal, 
       private usersService: UsersService, 
       private router: Router, 
       private ref: ChangeDetectorRef 
      ) { 

    ref.detach(); 
    setInterval(() => { 
    if (this.ref !== null && 
     this.ref !== undefined && 
     ! (this.ref as ViewRef).destroyed) { 
      this.ref.detectChanges(); 
    } 
}, 5000); 


    } 

    ngOnInit() { 
    this.getAllUsers(); 
    } 

    getAllUsers() { 
     this.subscription = this.usersService.getAll() 
     .subscribe(
      (data:any) => { 
      this.users = data.users; 
      console.log(data); 
      }, 
      error => { 
      alert("Error"); 
      }); 
    } 

    onCreateUser(form: NgForm){ 
    const name = form.value.name; 
    const email = form.value.email; 
    const password = form.value.password; 
    console.log(name); 
    this.usersService.addUser(name, email, password) 
     .subscribe(
      data => { 
      alert("User Created"); 
      console.log(data); 
      this.modalRef.close(); 
      this.usersService.clearCache(); 
      this.getAllUsers(); 
      }, 
      error => { 
      alert("Error Adding"); 
      console.log(error); 
      }); 
    } 

ngOnDestroy() { 
    clearInterval(this.intervalHolder); 
    this.subscription.unsubscribe() 
    } 

只要记住,你必须清除setInterval太上ngOnDestroy。在getAllUsers手动

export class UsersListComponent implements OnInit { 
    closeResult: string; 
    users: any; 
    subscription: Subscription; 
    modalRef: NgbModalRef; 

    intervalHolder: any; 

    constructor(private modalService: NgbModal, 
       private usersService: UsersService, 
       private router: Router, 
       private ref: ChangeDetectorRef 
      ) { 

    ref.detach(); 
    this.intervalHolder = setInterval(() => { 
     this.ref.detectChanges(); // you don't need this detectChanges, you can just use the one in the getAllUsers and everything will work as expected 
     this.getAllUsers(); 
    }, 5000);  

    } 

    ngOnDestroy() { 
    this.subscription.unsubscribe(); 
    clearInterval(this.intervalHolder); 
    } 

getAllUsers() { 
     this.subscription = this.usersService.getAll() 
     .subscribe(
      (data:any) => { 
      this.users = data.users; 
      // This will help you with the initial load delay. 
      this.ref.detectChanges(); 
      console.log(data); 
      }, 
      error => { 
      alert("Error"); 
      }); 
    } 

} 

UPDATE 运行detectChanges以除去初始延迟。

+0

它没有错误。但它加载用户列表太长 –

+0

@GraySingh它应该立即加载用户列表。 –

+0

谢谢你。但是,当我打开两个选项卡。我在一个选项卡中添加了一个用户,并立即输出。但是,第二个标签不接收。我应该重新加载它以获取新用户。 –

问题显然来自detectChanges()因为变化完成,在组件的破坏阶段调用的方法。

要解决此问题,请使组件实现OnDestroy,然后您需要取消调用this.ref.detectChanges()的更改。

export class UsersListComponent implements OnInit,OnDestroy { 
    // ... your code 

    ngOnDestroy() { 
    this.cdRef.detach(); 
    } 
} 
+0

生病维护我的代码?并在ondestroy中写入this.cdref.detach()? –

+0

你是什么意思 – Sajeetharan

+0

我会在我的代码中删除什么? –

我认为变化探测器被引用旧视图已被破坏! 在运行detectChanges之前,您可以检查以确保您的视图不被破坏。

setInterval(() => { 
    if (this.ref !== null && 
     this.ref !== undefined && 
     ! (this.ref as ViewRef).destroyed) { 
      this.ref.detectChanges(); 
    } 
}, 5000); 

希望得到这个帮助!

+0

它仍然加载用户列表太长。我已经为getAll()添加了高速缓存服务 –

+0

您可以尝试使用'markForCheck()'而不是'detectChanges()',因为这里是https://angular.io/api/core/ChangeDetectorRef#members? –

+0

我无法再看到用户列表。但出现在console.log –