微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Angular 异步 ngOnInit 实例化所需的属性

如何解决Angular 异步 ngOnInit 实例化所需的属性

我在 Angular 组件中有一个属性,通过 async ngOnInit 内的服务实例化:

txtItems: TextItems[];
 
constructor(private textItemService: TextItemService) {}

async ngOnInit() {    
    // await on promise
    this.txtItems = await this.textItemService.getAllAsync();
}

其中 getAllAsync 返回一个承诺:

async getAllAsync(): Promise<TextItems[]> {
   return await this.http.get<TextItems[]>(this.url).toPromise();
}

ngOnInit 异步运行,因此页面在加载项目之前不必挂起(这是一件好事),但有时 this.txtItems 会在加载完成之前从模板访问,这会导致异常。

我可以使 ngOnInit 不是 async,但是页面会加载缓慢。

我应该使用 txtItems: Promise<TextItems[]> 或类似的东西,然后使用 async 管道从任何地方访问它吗?等待异步服务的正确方法是什么?

解决方法

这是将 observable 转换为 Promise 的经典案例,没有任何经证实的优势。鉴于 HTTP 请求的输出仅在模板中使用,您可以从服务返回可观察对象,并使用 Sub PopulateSummary() Dim sht As Worksheet Dim currentRow As Long Dim oDict As Object Set sht = Worksheets("Summary") currentRow = 1 Set oDict = CalculateBalances() For Each itm In oDict.keys 'Column A of summary has case manager name sht.Cells(currentRow,1).Value = itm 'Column B of summary has M1 value sht.Cells(currentRow,2).Value = oDict(itm)(0) 'Column C of summary has M2 value sht.Cells(currentRow,3).Value = oDict(itm)(1) currentRow = currentRow + 1 Next itm End Sub Private Function CalculateBalances() As Object Dim oDict As Object Dim shtM1 As Worksheet Dim shtM2 As Worksheet Dim lRow As Long Dim keyValue As String Dim arr As Variant 'Get the Unique Case Managers dictionary 'This will contain each unique case manager as 'the key,and a 2 element array with M1 and M2 balances,'initialized to 0,0 Set oDict = GetUniqueCaseManagers 'Sheet with M1 balances Set shtM1 = Worksheets("Month1") 'Sheet with M2 balances Set shtM2 = Worksheets("Month2") 'Loop over each data value in the Month(n) worksheets,'If the Case Manager is in the dictionary,then add the 'totals. If not,I'm just ignoring it (maybe a case manager 'left. You can include custom logic here if you want) lRow = shtM1.Cells(Rows.Count,"A").End(xlUp).Row For i = 1 To lRow keyValue = shtM1.Cells(i,"A").Value If oDict.exists(keyValue) Then arr = oDict(keyValue) 'Assuming that the values being summed are in column B 'Update as necessary arr(0) = arr(0) + shtM1.Cells(i,"B").Value oDict(keyValue) = arr End If Next i 'Repeat for M2 lRow = shtM2.Cells(Rows.Count,"A").End(xlUp).Row For i = 1 To lRow keyValue = shtM2.Cells(i,"A").Value If oDict.exists(keyValue) Then arr = oDict(keyValue) 'Assuming that the values being summed are in column B 'Update as necessary arr(1) = arr(1) + shtM2.Cells(i,"B").Value oDict(keyValue) = arr End If Next i Set CalculateBalances = oDict End Function Private Function GetUniqueCaseManagers() As Object Dim oDict As Object Dim shtManagers As Worksheet Dim lRow As Long Dim keyValue As String Set oDict = CreateObject("Scripting.Dictionary") 'Point to the sheet with the case managers Set shtManagers = Worksheets("CaseManagers") 'Last Row of Column H to get case managers lRow = shtManagers.Cells(shtManagers.Rows.Count,"H").End(xlUp).Row For i = 1 To lRow keyValue = shtManagers.Cells(i,"H").Value Dim aTemp(0 To 1) As Double aTemp(0) = 0 aTemp(1) = 0 If Not oDict.exists(keyValue) Then oDict.Add keyValue,aTemp End If Next i Set GetUniqueCaseManagers = oDict End Function 管道在模板中使用它的值。

服务

async

组件

getAllAsync(): Observable<TextItems[]> {
   return this.http.get<TextItems[]>(this.url);
}

模板

public txtItems$: Observable<TextItems[]>;

constructor(private textItemService: TextItemService) {
  this.txtItems$ = this.textItemService.getAllAsync();   // <-- no `await`,only assignment
}

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