@ angular / маршрутизатор не работает внутри приложения angular.js - PullRequest
0 голосов
/ 06 сентября 2018

Я работаю над постепенным переходом большого приложения angular.js (которое использует ui-router) на angular, и я выбрал использование приложения angular.js в качестве основы и перенастраиваем разные маршруты по одному, поэтому что, как только я закончу, я сразу переключу все на угловое.

Вот шаги, которые я выполнил:

Загрузите приложение angular.js в моем файле main.ts:

export function bootstrapAngular(extra: StaticProvider[]): any {
  setAngularJSGlobal(angular);
  if (environment.production) {
    enableProdMode();
  }
  return platformBrowserDynamic(extra)
    .bootstrapModule(AppModule)
    .catch(err => console.log(err));
}

const downgraded = angular
  .module('downgraded', [downgradeModule(bootstrapAngular)])
  .directive('appRoot', downgradeComponent({ component: RootComponent, propagateDigest: false }))
  ;

angular.bootstrap(document, ['app', downgraded.name]);

Внутри моего index.html

<app id="app"></app>

Это отлично работает.

Внутри моего основного компонента angular.js я добавляю тег моего пониженного основного компонента Angular:

<div class="app__view" id="appContent">
  <ui-view></ui-view>
  <app-root></app-root>
</div>

Так настроен мой основной модуль

const COMPONENTS = [
  TestComponent,
  RootComponent,
];

@NgModule({
  declarations: COMPONENTS,
  imports: [
    BrowserModule,
    NxModule.forRoot(),
    RouterModule.forRoot(routes, {
      initialNavigation: 'enabled',
      useHash: true
    })
  ],
  providers: [
    { provide: APP_BASE_HREF, useValue: '/' }
  ],
  entryComponents: COMPONENTS,
  exports: COMPONENTS
})
export class AppModule {
  ngDoBootstrap(): void { }
}

Пока все отлично работает. Я вижу свой угловой компонент внутри моего приложения angular.js.

Проблема возникает, когда я добавляю к основному корневому компоненту Я вижу рендеринг на выходе маршрутизатора, но ничего рядом с ним, даже если маршрут совпадает.

export const routes: Route[] = [
  { path: 'dashboard', component: TestComponent }
];

Когда я указываю своему браузеру / # / dashboard , это трассировка маршрутизатора, которую я вижу:

router tracing

А тестовый компонент просто не рендерится.

enter image description here

Мне нужна помощь, не могу придумать, что еще попробовать.

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

Решение проблемы:

  • Полное избавление от UrlHandlingStrategy
  • Отключение начальной навигации
  • Создание пустых маршрутов в обеих конфигурациях маршрутов
  • Внедрение маршрутизатора ng2 в приложение ng1 и добавление следующей логики

    angular.module('app').config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
      $stateProvider.state('ng2', { });
    
      $urlRouterProvider.otherwise(($injector, $location) => {
        const $state = $injector.get('$state');
        const ng2Routes = ['dashboard'];
        const ng2Router = $injector.get('ng2Router');
        const url = $location.url();
        if (ng2Routes.some(feature => url.startsWith('/' + feature))) {
          $state.go('ng2');
          ng2Router.navigate([url]);
        } else {
          $state.go('messages');
        }
      });
    }]);
    
0 голосов
/ 12 сентября 2018

Прежде всего: если вы хотите перейти на гибрид и начать перемещать части ng1 в ngx, вам нужно запустить приложение ng1 из ngx, как и раньше, но не путем понижения:

platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
  (<any>platformRef.instance).upgrade.bootstrap(document.body, ['nameOfNg1App']);
});

Чем вы должны предоставить точку входа для ui-router в вашем app.component.html:

<div ui-view></div>

Вам также необходимо предоставить стратегию обработки URL, чтобы указать angular, какие маршруты обрабатывать. У меня был AppRoutingModule, который был импортирован AppModule. И этот предоставил обработчик:

@NgModule({
  imports  : [
    RouterModule.forRoot(routes, {useHash: true})
  ],
  exports  : [
    RouterModule
  ],
  // provide custom UrlHandlingStrategy to separate AngularJs from Angular routes
  providers: [
    {
      provide : UrlHandlingStrategy,
      useClass: Ng1Ng2UrlHandlingStrategy
    }
  ]
})
export class AppRoutingModule {
}

В стратегии обработки я использовал префиксы пути для отделения ng1 от маршрутов ngx, но при необходимости вы можете выбрать более простое разделение:

import { UrlHandlingStrategy } from '@angular/router';

export class Ng1Ng2UrlHandlingStrategy implements UrlHandlingStrategy {
    private ng1Urls: string[];

    constructor() {
        this.ng1Urls = [
            'prefix1',
        ];
    }

    shouldProcessUrl(url) {
        url = url.toString();
        return this.ng1Urls.findIndex(ng1Url => new RegExp(`^\/${ng1Url}([|\?|\/](.*)){0,1}$`).test(url)) === -1;
    }

    extract(url) {
        return url;
    }

    merge(url, whole) {
        return url;
    }
}

Да, и по ряду причин мне пришлось придерживаться # URL-адресов при работе с гибридом.

С этой настройкой вы запускаете приложение ngx, в котором есть контейнер, который запускает ui-router. В вашем приложении ng1 вы можете использовать устаревшие компоненты и сервисы ngx. Чтобы иметь ngx-маршруты и маршруты ng1 параллельно, ваш (ngx) app.component.html состоит из

<div ui-view></div>
<router-outlet></router-outlet>

Более подробную информацию об этой стратегии вы найдете здесь: https://blog.nrwl.io/upgrading-angular-applications-upgrade-shell-4d4f4a7e7f7b

...