3

I have two modules:

1st:

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,

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

export class AppModule { }

2nd:

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,

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

export class AppModule { }

and shared module with static .forRoot()

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

My DumyServise has some prop 'paramd' and I want to watch changes through modules

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

In both components of modules (1st and 2nd) I have

private ds: DumyService

in constructors.

Then, let's say I have some onclick method in some component of first module component, that changes

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

And I want to have this changes in both modules. How can I handle that?

WebArtisan
  • 3,996
  • 10
  • 42
  • 62
  • Why you want to have 2 root modules? – Kamil Myśliwiec Sep 25 '16 at 11:39
  • Because I need separate modules in different dom parts of my app. And I dnt know, how I can run it without some component directive – WebArtisan Sep 25 '16 at 11:45
  • In angular1 it was easier to have root component in tag. In A2 I don't see that possibility. A2 runs only through custom directive. Am I wrong? – WebArtisan Sep 25 '16 at 11:52
  • For those who is still looking for the answer in 2020, with Angular 9, it introduces provideIn: 'platform' service which can share data between two root modules. FYI: https://stackoverflow.com/questions/61454317/angular-9-platform-bootstrap-multiple-modules-run-multiple-applications-on-the – Nguyen Tran Apr 28 '20 at 04:43

1 Answers1

4

There are several similar questions that will help you

The main idea is create an instance of SharedService and use it as extraProviders when bootstrapping both components.

var sharedService = new SharedService();

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

Plunker Example

Maybe the best way is using one instance of platform:

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

Plunker Example

There is important thing(as @Günter said)

The subscribing application needs to invoke change detection when it receives a new value from the other Angular application because this code is invoked in the zone of the sending Application.

That's why i am using cd.detectChanges() in examples above.

But i want to show one trick. We "can bootstrap module with known Zone". This way we needn't worry about the call of detectChanges. Both application will work within one 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

Hope it helps someway!

Community
  • 1
  • 1
yurzui
  • 205,937
  • 32
  • 433
  • 399
  • I have tried to bootstrap two modules on the same page. It works as expected that they are have their own DI, NgZone, Routing, but I didn't find any official document about that, is there any side effect if we run bootstrap module more than one? Thanks. – Nguyen Tran Apr 27 '20 at 03:49