首页 > 解决方案 > 在角度 5 中调用服务后绑定丢失

问题描述

我希望通过参数 id 更改我的 url。问题是数据很大,所以我想在开始时加载整个数据。但是我发现一旦 url 更改,代码就会转到 ngOnInit 并且数据丢失。所以我必须重新加载它,它非常慢。所以我创建了一个全局服务类来存储数据,如果 url 发生变化,那么我比较数据是 null 还是 undefined。如果它为空,那么我从全局服务中检索数据。当然,我一开始就存储数据。它看起来不错。但是我发现了一件很疯狂的事情,如果代码在 getDataFromGlobalService 方法上运行,有时表单或文本框上的绑定会丢失。我想可能是异步问题或其他问题。

const url = 'apps/mycase/';
this.router.navigate([url], {queryParms: {id: this.id}});
if(this.data)
this.loadingData();
else
this.getDataFromGlobalService();


ngOnInit() {
   this.data = this.globalService.getData();
   this.loadDropDownData();
}

getDataFromGlobalService 方法

private getDataFromGlobalService() {
 // here still binding
   if(!this.data) {
        this.service['some'].get().subscribe(d => {
            this.data = d;
            this.globalService.setBackupData(this.data);
         };
   }
   else { // the binding lost here if code arrive here
       otherthings();

   }
}

The global service is simple.

@Injectable()
export class GlobalService {
   public data: any;
   constructor() {
       this.data = null;
   }
   public setBackData = (data: any) => {
        this.data = data;
   }

   public getData = () => {
      return this.data;
   }
}
    }

标签: angulardata-binding

解决方案


这就是 javascript 和对象引用存储的工作原理。更改服务级别引用不会更改之前存储旧引用的所有其他服务或组件中的引用。组件不存储对服务引用的引用,它们存储对服务在分配时引用的任何对象的引用。这就是你使用 rxjs 的原因。

   @Injectable()
   export class GlobalService {
     private dataSource = new BehaviorSubject<any>(null); // private subject, behavior subject will remember last value
     getData$ = this.dataSource.asObservable(); // public observable
     constructor() {
       this.data = null;
     }
     public setBackData = (data: any) => {
       this.dataSource.next(data); // call next to set new data
     }
   }


ngOnInit() {
   this.sub = this.globalService.getData$.subscribe(data => this.data = data); // subscribe and assign, store subscription
   this.loadDropDownData();
}

ngOnDestroy() {
  this.sub.unsubscribe(); // unsubscribe to avoid memory leaks
}

推荐阅读