【问题标题】:Angular - How to make sure that data is loaded only onceAngular - 如何确保数据只加载一次
【发布时间】:2019-10-02 12:04:42
【问题描述】:

当页面加载时,数据被正确获取并显示,然后在离开页面时再次获取数据并加倍到当前数组中。如果我有项目:A,B,C,那么我将拥有A,B,CA,B,C。

现在我有一个简单的组件来检查我是否需要再次获取数据。但是,它似乎被绕过了。我看过thisand thisas well as this。

//home.ts

export class Home implements OnInit, OnDestroy{
  conversations: Array<any>; 

async ngOnInit() {
  this._chatInit();
}

private async _chatInit() {
  this.dataService.loadConversations(); //getter for local storage

  const data = this.messageStorage.hasChats();

  if (data.length) {
    //there is data already loaded
    this.conversations = data;
  } else {
    //there is an empty array, subscribe to it.
    this.messageStorage
    .getChatList$()
    .subscribe(conversation => {
      console.log('Conversation', conversation)
      this.conversations = conversation;
    });
  }
}

//dataService
export class DataService {

  //the object where it is all stored
  private conversations: any = {
    peerToPeer: {},
    groups: {},
  };

  private listOfChats: Array<any> = new Array<any>();
  private bsListOfChats$: BehaviorSubject<any> = new BehaviorSubject<any>(this.listOfChats); 

  public loadConversations() {
    this.storage.get('conversations').then(chat=> {
      this.conversations = chat;
      this.formatChats(this.conversations);//converts the Object to an Array so *ngFor directive can be used
   });
  }

  public hasChats() {
    return this.listOfChats;
  }

  public getChatList$() {
    return this.bsListOfChats$;
  }

}

澄清一下,我想要加载一次n 聊天。当我离开页面并返回时,我希望加载相同的 n,不多也不少。

感谢大家的帮助!

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    看看TransferState它是用来在服务器端(角度通用)和客户端之间传输数据的,但我认为它只用于客户端是可以的

    import {makeStateKey, TransferState} from '@angular/platform-browser';
    
    export class DataService {
    
    //the object where it is all stored
    private conversations: any = {
        peerToPeer: {},
        groups: {},
    };
    
    constructor(
        private state: TransferState,
    ) {
    
    }
    
    private listOfChats: Array<any> = new Array<any>();
    private bsListOfChats$: BehaviorSubject<any> = new BehaviorSubject<any>(this.listOfChats);
    
    public loadConversations() {
        const stateKey = makeStateKey('conversations'); // 1 create stateKey
        const data = this.state.get(stateKey, null as any); // 2 get data from state
        if (data) { // 3 if data in state use it
            this.conversations = data;
        } else {
            this.storage.get('conversations').then(chat=> {
                this.conversations = chat;
                this.formatChats(this.conversations);//converts the Object to an Array so *ngFor directive can be used
                this.state.set(stateKey, {...this.conversations}); // 4 set data to storage
            });
        }
    }
    
    public hasChats() {
        return this.listOfChats;
    }
    
    public getChatList$() {
        return this.bsListOfChats$;
    }
    

    }

    快速编辑您的代码,可以用更好的方式重写

    【讨论】:

    • 从@ionic/storage 获取数据时,不会发出任何http请求
    • 没关系。或者我不明白你的问题(。请参阅我的答案中的示例
    • 好吧,对不起,当你发布它时,没有代码抱歉。
    • 好吧,看起来解决了最初的问题,看起来我需要编辑我的代码,以便它会更新状态并相应地删除状态,因为当我添加到状态时它没有添加到数组的项目。无论如何,感谢您对此的帮助!
    • 不明白如何将项目添加到数组中。也许您应该将不同的 stateKey 添加到不同的数据?例如:makeStateKey(`chat_${id}`)。并更新特定键的状态意味着重置此键的完整数据。
    【解决方案2】:

    这样做:

    @Component({
      //...
      changeDetection: ChangeDetectionStrategy.OnPush
    })
    

    签出:https://blog.angular-university.io/how-does-angular-2-change-detection-really-work/

    【讨论】:

    • 试过了,它不会进行初始加载,重新输入后会继续加载。
    • wait 等一下,为什么在 ngOnInit 上是异步的?好吗?因为我从来没有表现出这样的用途。 ngOnInit 应该是一个普通函数,你可以在那里放置任何异步代码,尝试修复它并修复 _chatInit 以便它会返回一些东西来测试它。顺便说一句,如果你不在那里使用 await 关键字,你为什么要让 _chatInit 异步?你可以使用一个简单的承诺
    • 它在那里是因为在 init 中有一个对存储的异步调用,但是自从我移动了这个调用后,我就把它取下来了,抱歉,我这边的错字:^)
    猜你喜欢
    • 2011-01-02
    • 2016-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-07
    • 1970-01-01
    • 2020-06-04
    相关资源
    最近更新 更多