代码之家  ›  专栏  ›  技术社区  ›  Andrey Ashurko

角度通用破坏模量ref

  •  1
  • Andrey Ashurko  · 技术社区  · 7 年前

    是否可以避免破坏moduleRef并将其重新用于下一个请求(如在浏览器中工作)?应用程序花费太多时间重新填充存储(API请求),所以我找到了缓存它的可能性。

    以下是源代码 ngx-universal/express-engine

    function handleModuleRef(moduleRef: NgModuleRef<{}>, callback: Function, req, res) {
        const state = moduleRef.injector.get(PlatformState);
        const appRef = moduleRef.injector.get(ApplicationRef);
    
        appRef.tick();
        appRef.isStable
            .filter((isStable: boolean) => isStable)
            .first()
            .subscribe((stable) => {
                const bootstrap = moduleRef.instance['ngOnBootstrap'];
                bootstrap && bootstrap();
    
                if (!res || !res.finished) callback(null, state.renderToString());
                moduleRef.destroy(); // remove this line and avoid creating new instance of NgModuleRef every request
            });
    }
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Andrey Ashurko    7 年前

    调试帮助我理解它是如何工作的,我实现了这样的代码:

    function handleModuleRef(moduleRef: NgModuleRef<{}>, callback: Function, req, res) {
        const state = moduleRef.injector.get(PlatformState);
        const appRef = moduleRef.injector.get(ApplicationRef);
        const router = appRef.components[0].instance.router;
        const zone = appRef.components[0].instance.zone;
        zone.run(() => {
            router.navigateByUrl(req.originalUrl);
        });
        appRef.isStable
            .filter((isStable: boolean) => isStable)
            .first()
            .subscribe((stable) => {
                const bootstrap = moduleRef.instance['ngOnBootstrap'];
                bootstrap && bootstrap();
    
                if (!res || !res.finished) callback(null, state.renderToString());
            });
    }
    

    我们需要在引导的主要组件中注入路由器和NgZone

    当我们进入“handleModuleRef”时,我们需要通过将新的导航url推送到路由器来破坏(isStable=false)应用程序的稳定性,以启动“changeDetector”。但若你们知道“isStable”是zone的一个属性(每个应用程序一个),诀窍是调用“router.navigateByUrl”在“zone.run(…)”内,以破坏zone的稳定性。 1) 应用程序处理新路由 3) 等待,直到稳定(区域内无人执行任务) 4) 渲染

    • 通过在内存中缓存所有应用程序并避免每个请求的引导,渲染速度加快了2-3-4倍
    • 内存泄漏是可能的(应用程序在docker中启动,如果意外掉落,它将重新启动)