angular - Угловой роутер: как передать данные в ленивый загрузочный модуль?




lazy-loading angular-routing (3)

У меня есть следующие пути маршрутизации для модуля моего приложения Angular:

@NgModule({
    imports: [
        RouterModule.forChild([
            {
                path: 'documents',
                data: { myObject: MyConstants.OPTION_ONE },
                children: [
                    {
                        path: ':ID_DOC',
                        children: [
                            { path: 'edit', component: EditDocumentComponent },
                            { path: '', component: DocumentDetailsComponent },
                        ]
                    },
                    { path: 'add', component: AddDocumentComponent },
                    { path: '', component: DocumentsListComponent }
                ]
            }
        ])
    ],
    exports: [
        RouterModule
    ]
})

export class DocumentsManagementRoutingModule {
}

Как вы можете видеть, я использую свойство data для передачи некоторых данных каждому пути в «документах», поэтому я могу получить их от любого из компонентов, объявленных в путях маршрутизации:

Например, вот как я получаю данные в DocumentDetailsComponent :

export class DocumentDetailsComponent implements OnDestroy {
    private obsData: Subscription;
    private option: any;

    constructor(private route: ActivatedRoute) {
        this.obsData = this.route.data.subscribe(data => {
            this.option = data['myObject'];
        });
    }

    ngOnDestroy(): void {
        this.obsData.unsubscribe();
    }
}

Теперь я изменил структуру маршрутизации всего приложения и вызываю указанный выше модуль из других модулей в режиме loadChildren загрузки, используя атрибут loadChildren . И я передаю данные таким же образом:

@NgModule({
    imports: [
        RouterModule.forChild([
            {
                path: 'users',
                loadChildren: 'app/documents/documents.module#DocumentsModule',
                data: { myObject: MyConstants.OPTION_ONE }},
            {
                path: ':ID_USER',
                children: [
                    { path: 'edit', component: EditUserComponent },
                    { path: '', component: UserDetailsComponent },
                ]
            },
            { path: 'add', component: AddUserComponent },
            { path: '', component: UserListComponent }
        ])
    ],
    exports: [
        RouterModule
    ]
})

export class UsersManagementRoutingModule {
}

И я сделал то же самое для всех других модулей, которые вызывают DocumentsManagementRoutingModule , изменив свойство myObject на MyConstants.OPTION_TWO , MyConstants.OPTION_THREE и так далее, в соответствии с моими потребностями.

Тогда, так как я не знаю модуль и связанный с ним путь, который вызывает мой ленивый загрузочный модуль, как получить свойство data из модуля вызывающей стороны?


Вы можете пройти по родительским маршрутам с помощью activRoute.pathFromRoot и получить данные от ближайшего предка, который их имеет. Нечто подобное похоже на работу:

  ngOnInit(): void {
    let idx = this.activatedRoute.pathFromRoot.length - 1;
    while(this.sharedData == null && idx > 0){
      this.sub = this.activatedRoute.pathFromRoot[idx].data.subscribe(subData => {

        if(subData.id)
          this.sharedData = subData;

        console.log('shared data', this.sharedData);
      });
      idx--;
    }
  }

https://plnkr.co/edit/K5Rb1ZvTvSQNM6tOLeFp


Почему бы вам не использовать сервис для обмена данными между модулями или какими-либо компонентами. Вы можете импортировать эту услугу у основного поставщика модулей и, следовательно, использовать ее во всех других модулях (модуль отложенной загрузки) и обмениваться данными.

Служба может иметь функции для установки и получения значений, и, следовательно, вы можете использовать эти функции в службах для получения необходимых данных.


@NgModule({
    imports: [
        RouterModule.forChild([
            {
                path: 'users',
                loadChildren: 'app/documents/documents.module#DocumentsModule',
                resolve : {
                     data: DataResolver
                }
            {
        ])
    ],
    exports: [
        RouterModule
    ]
})

export class UsersManagementRoutingModule {
}


@Injectable()
export class DataResolverimplements Resolve<Data> {
  resolve() {
    return this.serice.getData();
  }
}