在 Angular 10 中的 ngOnInit() 之后完全执行某些逻辑

如何解决在 Angular 10 中的 ngOnInit() 之后完全执行某些逻辑

我想在 ngOnInit()后执行一些逻辑,因为我想将逻辑与页面呈现分离。 我想到了 Angular 生命周期钩子,所以我将逻辑放在 ngAfterViewInit() 中,但它似乎与 ngOnInit() 同时被调用

代码示例:

export class SampleComponent implements OnInit,AfterViewInit{

  list = [];

  ngOnInit() {

    this.localDataService.getData().then( res =>{ //Promise call
      for (let o in res) { 
      this.list.push(res[o]) //the list get loaded
     })

   }


  ngAfterViewInit() {  // the intention is to process the list after it's loaded

   this.remoteDataService.getData().then(res => {

   for (let o in res) { 
     itemFound = this.list.find( (itemInList) => {return itemInList.id === res[o].id})

     //and some code to manipulate the item found from list
     itemFound = ....  // but the itemFound is always 'undefined'

      })

    }

}

根据 Angular 生命周期钩子,ngAfterViewInit() 应该在 ngOnInit()后执行,但代码运行结果表明并非如此。 itemFound 中的 ngAfterViewInit() 始终为“未定义”。

在 promise 调用之后,我尝试将代码块从 ngAfterViewInit() 放到 ngOnInit()itemFound 将获得正确的值。

谁能帮忙解释一下哪里出了问题?是不是因为 Promise 调用是异步的?

解决方法

因为 localDataService.getDataremoteDataService.getData 都是异步的,所以不确定哪个会先解决,localDataService.getData 可能在 ngOnInit 完成时还没有解决。

因此,即使您在 remoteDataService.getData 完成后立即调用 ngOnInit,也不确定在 localDataService.getData 将被解析时 remoteDataService.getData 是否已解析。

您必须检查 localDataService.getDataremoteDataService.getData 是否都已解析。一种解决方案如下。

export class SampleComponent implements OnInit,AfterViewInit{

  localList = [];
  remoteList = [];
  
  localListLoaded = false;
  remoteListLoaded = false;

  ngOnInit() {

    this.localDataService.getData().then( res =>{ //Promise call
      for (let o in res) { 
        this.localList.push(res[o]) //the list get loaded
      }
      localListLoaded = true;
      manipulate();
    });

   
    this.remoteDataService.getData().then(res => {
      for (let o in res) {
        this.remoteList.push(res[o]);
      }
      remoteListLoaded = true;
      manipulate();
    }

  }
  
  manipulate() {
    if (localListLoaded && remoteListLoaded) {
      // some code stuff for remoteList and localList      
    }
  }

}
,

根据 Angular 生命周期钩子,ngAfterViewInit() 应该在 ngOnInit() 之后执行,

是的。

但代码运行结果却相反。

它没有。您不是在 ngOnInit 中分配列表,而是在承诺回调中。一旦承诺得到解决,该回调将被调用,但 ngOnInit() 不会等待它发生。 (即使 angular 想要等待,它也不能,因为 angular 不知道 Promise 对象存在,更不用说您向它添加了回调 - 而且由于等待会冻结 UI,因此 angular 不想等待).

如果你想等到两个 promise 都解决了,那么你必须询问 promises,而不是 angular。这样做的简单方法是:

ngOnInit() {
  Promise.all([
    this.localDataService.getData(),this.remoteDataService.getData()
  ]).then(([list,data]) => {
    // work with list and data
  });
}
,

我通过 Rxjs 库中的 BehaviorSubject 实现了这一点,这基本上是一个可观察的模式。 重点是通知 ngAfterViewInit() 中的代码仅在列表数据准备就绪时启动。

代码示例:

export class SampleComponent implements OnInit,AfterViewInit{

  list = [];
  private listSub = new BehaviorSubject([]);
  listSubObservab = this.listSub.asObservable();

  ngOnInit() {

    this.localDataService.getData().then( res =>{ //Promise call
      for (let o in res) { 
      this.list.push(res[o]) //the list get loaded
       }
      this.listSub.next(this.list) //notify when list is ready
     })

   }


  ngAfterViewInit() {  // the intention is to process the list after it's loaded

    this.listSubObservab.subscribe(listLoaded => { //observer here,only triggered by notify

      this.remoteDataService.getData().then(res => {

      for (let o in res) { 
        itemFound = listLoaded.find( (itemInList) => {return itemInList.id === res[o].id})

      //and some code to manipulate the item found from list
      itemFound = ....  // Finally the itemFound has proper value

       }
      })

    }
 }

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?