如何在不同的 angular 库之间正确共享数据?

how to properly share data between different angular libraries?

我有一个 angular 10 的应用程序,其中包含我分离到不同库的用户部分 为了使其通用并在 github.

上发布

用户库包含以下模块: login-pagelogin-tabprofile-pageregister-tabshared.

登录选项卡模块需要为登录命令获取一些订阅参数。

所以我这样定义:

export type LoginCallback = (username: string, password: string) => Subscribable<LoginDataToken>;

现在,由于我将 login-pagelogin-tab 分开,我需要为它们创建一个不同的 forRoot() 以接收包含 loginCallback 变量的选项 class。

所以我创建了这个:

import {LoginCallback} from '@com-tuxin/user/src/lib/shared';

export class LoginTabOptions {

  constructor(public loginCallback: LoginCallback) {
  }

}

@Injectable()
export class LoginTabService {

  public loginCallback: LoginCallback|undefined;

  setLoginCallback(login: ((username: string, password: string) => Subscribable<LoginDataToken>) | undefined): void {
    this.loginCallback = login;
  }

}

现在,如果我不正确(也许我是正确的),我应该将 forRoot() 添加到 login-pagelogin-tab, 由于用户只需要login-page,我需要将回调转移到login-tab

所以这是我的全部 login-page.module.ts:

import {ModuleWithProviders, NgModule} from '@angular/core';
import {LoginPageComponent} from '@com-tuxin/user/src/lib/login-page/login-page.component';
import {FlexModule} from '@angular/flex-layout';
import {MatTabsModule} from '@angular/material/tabs';
import {RegisterTabModule} from '@com-tuxin/user/src/lib/register-tab';
import {LoginTabModule, LoginTabOptions, LoginTabService} from '@com-tuxin/user/src/lib/login-tab';
import {RouterModule, Routes} from '@angular/router';

const routes: Routes = [  {path: 'login', component: LoginPageComponent} ];


@NgModule({
  declarations: [
    LoginPageComponent
  ],
  imports: [
    RegisterTabModule,      ### LINE BLOW IS PROBLEMATIC ###
 ###-->      LoginTabModule.forRoot({loginCallback: this.loginTabService.loginCallback}),
 ################   
 FlexModule,
    MatTabsModule,
    RouterModule.forChild(routes)

  ],
  exports: [
    LoginPageComponent
  ]
})
export class LoginPageModule {

  constructor(private loginTabService: LoginTabService) {
  }

  // tslint:disable-next-line:no-any
  static forRoot(options: LoginTabOptions): ModuleWithProviders<any> {
    return {
      ngModule: LoginPageModule,
      providers: [ {
        provide: LoginTabService,
        useFactory: () => {

          const loginTabService = new LoginTabService();
          loginTabService.setLoginCallback(options.loginCallback);
          return( loginTabService );

        }
      } ]
    };
  }

intellij returns 一个错误 Object is possibly undefined。我猜想在那个部分 this 它不是实际 class.

this

所以首先.. 我的方法有意义吗?用户将加载 login-page 并向其添加 forRoot(),我的 login-age 模块将加载 login-tab 并将向其提供 forRoot() 回调,它将使用它。

如果不是.. 有何不同?

如果是..我该如何更正它?模块需要使用 forRoot() 获取服务并使用 forRoot() 将其发送到 login-tab 模块。

您可以尝试以下方法:将 LoginTabModule 添加到 imports 数组并将 LoginTabModule providers 展开到 forRoot 部分:

@NgModule({
  imports: [
    LoginTabModule,  <============== tell Angular that you're going
                                     to use declarables from this module
    ...

  ],
  ...
})
export class LoginPageModule {
  static forRoot(options: LoginTabOptions): ModuleWithProviders<any> {
    return {
      ngModule: LoginPageModule,
      providers: [
        {
          provide: LoginTabService,
          useFactory: () => {
            ...
          }
        },
        ...LoginTabModule.forRoot(options).providers, <== use providers from LoginTabModule
      ]
    };
  }
}