我已将此GitHub存储库中的应用程序用作我的角度路由问题的演示应用程序。
应用程序运行良好。因此,应用程序本身不是我的重点,因为它很简单,但是如果您愿意,您可以完全访问它的代码!
我的问题是,每次在这个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和构造函数:
我甚至尝试使用以下片段进行导航,得到了相同的结果!:
import { Router, ActivatedRoute } from '@angular/router';
constructor(
private router: Router
) { }
this.router.navigate(['/contacts']);
问题是如何防止这种新的实例化!?
特别是,当我们从第二页返回到第一页时。我正在寻找一种类似于单例的技术,它只会在我们第一次访问某个路由时实例化组件,而在其他时间访问该路由时,我们会得到组件的相同瞬间。
实际上,这个应用程序并不是我正在开发的主要应用程序,我的主要问题是在其他应用程序中,我使用了订阅技术来共享数据,然后当我有一个组件的多个实例时,不同实例中的以下代码将被激发,结果不符合预期。为什么?因为如果(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();
}
}
}
与您对@anatoli的评论相关,使用RouteReuseStrategy将解决此问题。例如,请参阅此处。首先我们必须创建一个服务类:
RouterUseService。ts
import {
RouteReuseStrategy,
ActivatedRouteSnapshot,
DetachedRouteHandle,
RouterModule,
Routes,
UrlSegment
} from '@angular/router';
export class RouteReuseService implements RouteReuseStrategy {
private handlers: { [key: string]: DetachedRouteHandle } = {};
shouldDetach(route: ActivatedRouteSnapshot): boolean {
if (!route.routeConfig || route.routeConfig.loadChildren) {
return false;
}
let shouldReuse = false;
console.log('checking if this route should be re used or not’, route');
if (route.routeConfig.data) {
route.routeConfig.data.reuse ? shouldReuse = true : shouldReuse = false;
}
return shouldReuse;
}
store(route: ActivatedRouteSnapshot, handler: DetachedRouteHandle): void {
console.log('storing handler');
if (handler) {
this.handlers[this.getUrl(route)] = handler;
}
}
shouldAttach(route: ActivatedRouteSnapshot): boolean {
console.log('checking if it should be re attached');
return !!this.handlers[this.getUrl(route)];
}
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
if (!route.routeConfig || route.routeConfig.loadChildren) {
return null;
};
return this.handlers[this.getUrl(route)];
}
shouldReuseRoute(future: ActivatedRouteSnapshot, current: ActivatedRouteSnapshot): boolean {
let reUseUrl = false;
if (future.routeConfig) {
if (future.routeConfig.data) {
reUseUrl = future.routeConfig.data.reuse;
}
}
const defaultReuse = (future.routeConfig === current.routeConfig);
return reUseUrl || defaultReuse;
}
getUrl(route: ActivatedRouteSnapshot): string {
if (route.routeConfig) {
const url = route.routeConfig.path;
console.log('returning url', url);
return url;
}
}
}
下一步,我们必须对app.module.ts做一些改变:
providers: [{provide: RouteReuseStrategy, useClass: RouteReuseService}],
bootstrap: [AppComponent]
在最后一步中,我们必须将组件的“重用”设置为true,我们希望在应用程序中重用它(app-routing.modules.ts)。例如,这里我们想要重用DetailComponent:
const routes: Routes = [{ path: '', component: HomeComponent },
{
path: 'detail', component: DetailComponent, data: {
reuse: true
}
}, { path: 'item', component: ItemComponent }];
问题内容: 想象一下以下课程: 我想重新启动线程以防万一。这不起作用。因为线程只能启动一次。第一个问题。为什么是这样? 据我所知,我必须重新创建的每个实例并调用以再次启动线程。如果是s,这不是很实际。我必须读取旧值的当前值,创建一个新值,并使用旧值在新对象中设置参数。第二个问题:这可以用更聪明,更轻松的方式完成吗? 问题答案: 之所以以这种方式实现threading.Thread,是为了保持线程对
我正在学习React钩子,这意味着我将不得不从类转移到函数组件。以前,在类中,我可以拥有与状态无关的类变量,我可以在不重新呈现组件的情况下更新这些变量。现在我试图用钩子重新创建一个组件作为函数组件,我遇到了这样一个问题:我不能(就我所知)为该函数创建变量,因此存储数据的唯一方法是通过钩子。然而,这意味着每当该状态更新时,我的组件将重新呈现。 我已经在下面的示例中说明了这一点,我试图将类组件重新创建
我正在开发一个应用程序播放器。请看下面的图片: 进度条必须显示当前时间,但每次勾选,我的组件都会重新呈现所有内容。这导致我的应用程序运行缓慢。 这是我的代码:
我从这里修改了以下组件定义,如下所示。但是,与示例不同的是,每次在组件上移动鼠标时,组件都会重新呈现。 重新渲染非常引人注目: 有人知道为什么会这样吗?
我对react还比较陌生,我一直在分解一个web应用程序,并用react组件替换部分。我现在正在开发一个组件,其中包含我创建的几个不同组件。 在新组件中,我在componentDidMount函数中进行API调用,并创建子组件。乍一看,一切看起来都很完美,但当我们在其中一个子组件中进行状态更改,然后在父组件中进行更改时,子组件将其状态重置为更改之前的状态。 我知道发生了什么,州政府没有被传递给家长
问题内容: 旋转屏幕时,WebView会重新加载整个页面。我无法使用此功能,因为我的某些内容包含动态/随机材料。当前,屏幕旋转时会从loadUrl()方法重新加载原始URL。 知道我的代码有什么问题吗? MainActivity.java AndroidManifest.xml 问题答案: 我认为主要问题是您调用了web.loadUrl(webURL); 当saveInstanceState!=