Маршрутизация гибридных приложений 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 };