【发布时间】:2020-05-17 19:20:49
【问题描述】:
我已使用此 GitHub repository 中的应用程序作为我的角度路由问题的演示应用程序。
应用程序运行良好。因此,应用程序本身不是我的重点,因为它很简单,但是如果您愿意,您可以完全访问它的代码!
我的问题是,每次在这个 Angular 应用中导航时,都会生成一个相关组件的新实例。
我在代码中做了一些更改来说明这个实例化。我添加了一个简单的计数器如下:
export class ContactListComponent implements OnInit {
contacts: any[] = [];
counter = 0; //<--- counter definition
constructor(private contactService: ContactService) {
console.log("List Component constructor: #" + ++this.counter); //<--- usage #1
}
ngOnInit() {
console.log("List Component ngInit: #" + ++this.counter); //<--- usage #2
this.contactService.getContacts().subscribe((data: any[]) => {
this.contacts = data;
});
}
}
如果你看下图,我所做的每次导航都会生成一个新实例,因此每次都会重置计数器,并在控制台中显示 ngInit 和 constructor 已被再次调用又一次:
我什至尝试使用以下 sn-p 导航,得到了相同的结果!:
import { Router, ActivatedRoute } from '@angular/router';
constructor(
private router: Router
) { }
this.router.navigate(['/contacts']);
问题是如何防止这种新的实例化!?
特别是,当我们从第二页导航回第一页时。 我正在寻找一种像单例这样的技术,它只会在我们第一次访问路由时实例化组件,而在其他时候我们访问该路由时,我们会得到组件的相同瞬间。
实际上这个应用程序不是我正在开发的主要应用程序,我的主要问题是在我使用subscription technique 共享数据的其他应用程序中,然后当我有一个组件的多个实例时,以下代码在不同实例将被触发并且结果不符合预期。为什么?因为if (this.agreeTerms)会同时在不同的实例中具有不同的值!
navNext(next) {
this.next = next;
if (this.next === true && this.router.url.startsWith('/') && this.router.url.endsWith('/')) {
this.data.unsetNext();
if (this.agreeTerms) { //<-----
this.router.navigate(['/form']);
} else {
this.error = 'Please accept the terms and conditions';
this.scrollBottom();
}
}
}
【问题讨论】:
-
这就是 Angular 的工作方式。它将为路由器插座重新创建组件。为什么不希望重新创建组件?如果您的问题是组件正在从后端加载数据,这可能会减慢组件的渲染速度,那么您应该考虑使用可以缓存数据的服务。
-
不,实际上问题是它会保留实例并且不会销毁它们。例如在 UI5 等其他 JS 框架中,它不会每次都生成一个新实例。我认为应用程序组件似乎是一个父组件,并且每次创建或激活的实例都存在时导航!
-
@MahdiJ.Ansari - 逆流而上从来都不是一个好主意。由于这是路由器在 Angular 中的工作方式,我建议考虑其他可能性,例如(重新)设计您的应用程序,以使创建新组件实例不会成为问题。
-
尝试使用
Locationfromcommonstackoverflow.com/questions/35446955/how-to-go-back-last-page -
你试过改变
RouteReuseStrategy吗? medium.com/@juliapassynkova/…