typescript - Angular 9:如何在组件代码中的 canDeactivate 函数中访问 HTML 中 async pipe 的结果?
在我的 Angular 9 项目中,我有这样的模板代码,用于显示来自服务的对象。并且在用户在页面上的交互时,将对象传递给组件代码。
<div *ngIf="report$ | async as report">
...
<div>{{report.Title}}</div>
<button (click)="DoSomething(report)" >Do something</button>
...
</div>
然而,我如何从组件代码中访问异步管道的报告对象,而该代码并不是由页面触发的。例如,在用户从当前页面导航离开时的 CanDeactivate 函数中。
export class ReportComponent implements OnInit {
report$: Observable<Report>;
constructor(
private route: ActivatedRoute,
private router: Router,
private location: Location,
private reportService: ReportService
) { }
ngOnInit() {
this.report$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) => this.reportService.getReport(Number(params.get('id')))
)
);
}
DoSomething(report: Report) {
...
}
canDeactivate(): Observable<boolean> | boolean {
if isReportChanged("How to access the report object from here?")
return false;
return true;
}
}
答案#1
这可以如下实现(供参考)
TS 文件
import { Component , OnInit} from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
})
export class AppComponent implements OnInit {
reports :any[] = [
{Title:"Report 1"},
{Title:"Report 2"},
{Title:"Report 3"},
{Title:"Report 4"},
{Title:"Report 5"}
]
ngOnInit(){
this.reports.forEach(s=>Object.assign(s,{IsTouched:false}));
//initialize a new field to mark as touched.
}
DoSomething(report) {
this.reports.find(s=>s.Title == report.Title).IsTouched = true;
}
OnDeactive()
{
console.log(JSON.stringify(this.reports.filter(s=>s.IsTouched)))
}
}
HTML
<div *ngFor="let report of reports">
<div>{{report.Title}} - {{report.IsTouched}}</div>
<button (click)="DoSomething(report)" >Do something</button>
</div>
<br>
<button (click)="OnDeactive()">Back Button Simulate</button>
在这里,您可以在组件的返回按钮事件处理程序中调用 OnDeactive()。
答案#2
我建议在你的 HTML 中使用如下方式:
<ng-container *ngIf="report$ | async as report">
{{ setReportData(report) }}
</ng-container>
这应该是调用一个函数在数据流上运行
然后在你的 TS 中定义该函数以及如何处理它接收到的数据。如果你像示例那样操作,那么会设置一个后台报告变量,该变量随后可以在其他函数调用中使用:
report: Report;
...
setReportData(report: Report): void{
if(this.report === null || this.report === undefined) {
this.report = report
}
}
