如何解决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 举报,一经查实,本站将立刻删除。