Маршрутизация гибридных приложений Angular и AngularJS: угловой компонент как дочернее состояние не отображается

Сначала краткое введение в проект и общие настройки.

Это угловое / угловое приложение JS. Я интегрировал Angular пару недель назад. В отличие от многих различных учебных пособий, использующих UpgradeModule, мне фактически пришлось использовать downgradeModule - проект довольно большой, и UpgradeModule вызвал много проблем с производительностью.

Существует общее родительское состояние (называемое приложением), и я хочу, чтобы угловой компонент был его дочерним элементом. Согласно документам это должно быть возможно ( https://github.com/ui-router/angular-hybrid)

Ограничения: В настоящее время мы поддерживаем маршрутизацию компонентов Angular (2+) или AngularJS (1.x) в пользовательский интерфейс AngularJS (1.x). Однако мы не поддерживаем маршрутизацию компонентов AngularJS (1.x) в пользовательский интерфейс Angular (2+).

Если вы создаете угловое (2+) пользовательское представление, то любое вложенное пользовательское представление также должно быть угловым (2+).

Из-за этого приложения должны быть перенесены, начиная с конечных состояний / представлений, и переходить к корневому состоянию / представлению.

Общая настройка выглядит следующим образом (упрощение):

app.module.ng1.ts

import { AppModule } from './app.module';

const bootstrapFn: any = (extraProviders: Array<StaticProvider>): any => {
    return platformBrowserDynamic(extraProviders).bootstrapModule(AppModule);
};
const downgradedModule: any = downgradeModule(bootstrapFn);

const appModule: angular.IModule = angular
    .module('app', [
        downgradedModule,
        // other project modules
    ]);

app.module.ts

@NgModule({
    imports: [
        BrowserModule,
        UIRouterUpgradeModule.forChild(),
    ],
    declarations: [
        AccountNg2Component,
    ],
    providers: [
    ],
    entryComponents: [
        AccountNg2Component,
    ],
})
class AppModule {
    public ngDoBootstrap(): void {}
}

export { AppModule };

TheAccountNg2Component - это то, к чему я действительно хочу обратиться. account.component.ts

@Component({
    selector: 'account',
    template,
})
class AccountNg2Component {
    @Input() public user: any;

    constructor() {}

}

export { AccountNg2Component };

Существует родительское состояние приложения, и я хочу, чтобы AccountNg2Component был его дочерним элементом. Конфигурация состояния выглядит следующим образом:

$stateProvider
    .state({
        parent: 'app',
        name: 'account',
        url: '/account',
        component: AccountNg2Component,
    });

Что бы я ни пробовал, это также приведет к следующим двум ошибкам:

Transition Rejection($id: 0 type: 6, message: The transition errored, detail: TypeError: Cannot read property 'when' of undefined)

TypeError: Cannot read property 'when' of undefined
at Ng2ViewConfig.load (views.js:47)
at eval (views.js:19)
at Array.map (<anonymous>)
at loadEnteringViews (views.js:19)
at invokeCallback (transitionHook.js:104)
at TransitionHook.invokeHook (transitionHook.js:116)
at eval (transitionHook.js:58)
at processQueue (angular.js:17169)
at eval (angular.js:17217)
at Scope.$digest (angular.js:18352)
at Scope.$apply (angular.js:18649)
at eval (angular.js:18952)
at completeOutstandingRequest (angular.js:6428)
at eval (angular.js:6707)
at ZoneDelegate.invokeTask (zone.js:420)
at Object.onInvokeTask (core.js:4961)
at ZoneDelegate.invokeTask (zone.js:419)
at Zone.runTask (zone.js:187)
at ZoneTask.invokeTask (zone.js:495)
at ZoneTask.invoke (zone.js:484)
at timer (zone.js:2053)

Я, наверное, что-то упустил в конфигурации, но я не могу понять это.


Что я уже пробовал:

Я посмотрел пример приложения ( https://github.com/ui-router/sample-app-angular-hybrid) и попытался создать его максимально похожим. Но они используют UpgradeModule вместо downgrade - я не знаю, изменит ли это что-нибудь для маршрутизатора.

Я старался

  • Добавление конфигурации состояния в UIRouterUpgradeModule.forChild() и UIRouterModule.forChild()
  • Создано "будущее состояние" в соответствии с https://github.com/ui-router/sample-app-angular-hybrid/blob/master/app/angularModule.ts#L10
  • Различные способы объявить состояние счета
  • Различные способы определения самого компонента учетной записи

Ошибка остается неизменной, поэтому я думаю, что мне не хватает какой-то части в моей конфигурации.

Если мое описание не поможет, я постараюсь настроить jsfiddle или что-то подобное


Обновление 1: Хорошо, я удалил декларацию состояния для учетной записи из поставщика состояния Angular 1 и вместо этого зарегистрировал ее только в UIRouterModule. Теперь, по крайней мере, ошибка исчезла, но состояние вообще не загружается (при попытке доступа к нему перенаправить в состояние по умолчанию)

1 ответ

Решение

Хорошо, мне наконец удалось решить проблему, благодаря подсказке из другой статьи ( /questions/39231311/kak-uskorit-prilozhenie-s-pomoschyu-gibrida-ui-router-ispolzuya-downgrademodule/39231317#39231317)

Просто приведу здесь еще раз:

Модуль Angular начальной загрузки нуждался в параметре типа "UIRouter" в конструкторе, иначе он не загрузил бы его состояния:

export class AppModule {
       constructor(private router: UIRouter) {
       // "router" needed in constructor to bootstrap angular states
}

Вам также необходимо импортировать UpgradeModule и UIRouterUpgradeModule. Таким образом, весь app.module.ts выглядит так:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ServiceBootstrapComponent } from '../../service-bootstrap';
import { AccountNg2Component } from '../../app/pages/account/account.ng2.component';
import { UIRouterUpgradeModule } from '@uirouter/angular-hybrid';
import { AccountState } from '../../app/pages/account/account.states';
import { CommonModule } from '@angular/common';
import { UIRouter, UIRouterModule } from '@uirouter/angular';
import { UpgradeModule } from '@angular/upgrade/static';

@NgModule({
    imports: [
        CommonModule,
        BrowserModule,
        UpgradeModule,
        UIRouterUpgradeModule,
        UIRouterModule.forChild({states: [AccountState]}),
    ],
    declarations: [
        ServiceBootstrapComponent,
        AccountNg2Component,
    ],
    providers: [
    ],
    entryComponents: [
        ServiceBootstrapComponent,
    ],
})
class AppModule {
    constructor(private router: UIRouter) {}
    public ngDoBootstrap(): void {}
}

export { AppModule };
Другие вопросы по тегам