【问题标题】:Changing shared data between root modules [duplicate]更改根模块之间的共享数据[重复]
【发布时间】:2016-09-25 11:28:53
【问题描述】:

我有两个模块:

第一个:

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,

        SharedModule.forRoot()
    ],
    declarations: [
        FirstComponent
    ],
    bootstrap: [ FirstComponent ]
})

export class AppModule { }

第二个:

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,

        SharedModule.forRoot()
    ],
    declarations: [
        ScndComponent
    ],
    bootstrap: [ ScndComponent ]
})

export class AppModule { }

并与静态 .forRoot() 共享模块

@NgModule( {} )
export class SharedModule {
    static forRoot() {
        return {
            ngModule    : SharedModule,
            providers   : [DumyService]
        }
    }
}

我的 DumyServise 有一些 prop 'paramd',我想通过模块观察变化

@Injectable()
export class DumyService {
    paramd : string;
}

在模块的两个组件(第一个和第二个)中我都有

private ds: DumyService

在构造函数中。

然后,假设我在第一个模块组件的某些组件中有一些 onclick 方法,它会改变

clickToChangeParam() {
        this.ds.paramd = 'new value';
}

我想在两个模块中都进行此更改。 我该如何处理?

【问题讨论】:

  • 为什么要拥有 2 个根模块?
  • 因为我需要在我的应用程序的不同 dom 部分中使用单独的模块。而且我不知道,如果没有一些组件指令 我怎么能运行它
  • 在 angular1 中,在 标签中有根组件更容易。在 A2 中,我看不到这种可能性。 A2 仅通过自定义指令运行。我错了吗?
  • 对于那些在 2020 年仍在寻找答案的人,Angular 9 引入了 provideIn: 'platform' 服务,可以在两个根模块之间共享数据。仅供参考:stackoverflow.com/questions/61454317/…

标签: angular


【解决方案1】:

有几个类似的问题会对你有所帮助

主要思想是创建SharedService 的实例,并在引导两个组件时将其用作extraProviders

var sharedService = new SharedService();

platformBrowserDynamic([{ provide: SharedService, useValue: sharedService }]).bootstrapModule(AppModule)
platformBrowserDynamic([{ provide: SharedService, useValue: sharedService }]).bootstrapModule(AppModule2)

Plunker Example

也许最好的方法是使用一个平台实例:

var platform = platformBrowserDynamic([SharedService]);
platform.bootstrapModule(AppModule)
platform.bootstrapModule(AppModule2)

Plunker Example

有重要的事情(正如@Günter 所说)

订阅应用程序需要调用更改检测 从另一个 Angular 应用程序接收一个新值,因为这 在发送应用程序的区域中调用代码。

这就是我在上面的示例中使用cd.detectChanges() 的原因。

但我想展示一个技巧。我们“可以用已知的Zone 引导模块”。这样我们就不用担心detectChanges的调用了。这两个应用程序都可以在一个Zone 中运行:

const platform = platformBrowserDynamic([SharedService]);
platform.bootstrapModule(AppModule).then((moduleRef: NgModuleRef<any>) => {
  const zone = moduleRef.injector.get(NgZone);
  (<any>platform)._bootstrapModuleWithZone(AppModule2, [], zone); // private method is bad!!!
}); 

Plunker Example

希望对你有所帮助!

【讨论】:

  • 我尝试在同一页面上引导两个模块。它们有自己的 DI、NgZone、Routing 可以按预期工作,但是我没有找到任何官方文档,如果我们运行多个引导模块有什么副作用吗?谢谢。
猜你喜欢
  • 2017-10-04
  • 1970-01-01
  • 1970-01-01
  • 2015-10-08
  • 1970-01-01
  • 2016-03-17
  • 1970-01-01
  • 1970-01-01
  • 2021-10-16
相关资源
最近更新 更多