@angular/router 无法在 angular.js 应用程序中工作
@angular/router not working inside an angular.js application
我正在努力将一个大的 angular.js 应用程序(使用 ui-router)一点一点地迁移到 angular,我选择使用 angular.js 应用程序作为一个基地并一次迁移不同的路线,这样一旦我完成我就立即将所有内容切换到 angular.
这些是我遵循的步骤:
在我的 main.ts 文件中引导 angular.js 应用程序:
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 应用程序中看到我的 angular 组件。
当我添加到我的主要根组件时出现问题
我可以看到 router-outlet 渲染但旁边什么也没有,尽管路线匹配。
export const routes: Route[] = [
{ path: 'dashboard', component: TestComponent }
];
当我将浏览器指向 /#/dashboard 时,这是我看到的路由器跟踪:
并且测试组件不呈现。
我需要一些帮助,想不出还有什么可以尝试的。
首先:如果你想混合并开始将 ng1 的部分移动到 ngx,你需要像你一样从 ngx bootstrap 你的 ng1 应用程序,但不是通过降级:
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
(<any>platformRef.instance).upgrade.bootstrap(document.body, ['nameOfNg1App']);
});
你应该在 app.component.html:
中为 ui-router 提供入口点
<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-routes 和 ng1 路由,您的 (ngx) app.component.html 包含
<div ui-view></div>
<router-outlet></router-outlet>
您可以在此处找到此策略的更多详细信息:https://blog.nrwl.io/upgrading-angular-applications-upgrade-shell-4d4f4a7e7f7b
涉及的解决方案:
- 完全摆脱 UrlHandlingStrategy
- 禁用初始导航
- 在两个路由配置中创建空路由
在ng1应用中注入ng2路由,添加如下逻辑
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');
}
});
}]);
我正在努力将一个大的 angular.js 应用程序(使用 ui-router)一点一点地迁移到 angular,我选择使用 angular.js 应用程序作为一个基地并一次迁移不同的路线,这样一旦我完成我就立即将所有内容切换到 angular.
这些是我遵循的步骤:
在我的 main.ts 文件中引导 angular.js 应用程序:
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 应用程序中看到我的 angular 组件。
当我添加到我的主要根组件时出现问题 我可以看到 router-outlet 渲染但旁边什么也没有,尽管路线匹配。
export const routes: Route[] = [
{ path: 'dashboard', component: TestComponent }
];
当我将浏览器指向 /#/dashboard 时,这是我看到的路由器跟踪:
并且测试组件不呈现。
我需要一些帮助,想不出还有什么可以尝试的。
首先:如果你想混合并开始将 ng1 的部分移动到 ngx,你需要像你一样从 ngx bootstrap 你的 ng1 应用程序,但不是通过降级:
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
(<any>platformRef.instance).upgrade.bootstrap(document.body, ['nameOfNg1App']);
});
你应该在 app.component.html:
中为 ui-router 提供入口点<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-routes 和 ng1 路由,您的 (ngx) app.component.html 包含
<div ui-view></div>
<router-outlet></router-outlet>
您可以在此处找到此策略的更多详细信息:https://blog.nrwl.io/upgrading-angular-applications-upgrade-shell-4d4f4a7e7f7b
涉及的解决方案:
- 完全摆脱 UrlHandlingStrategy
- 禁用初始导航
- 在两个路由配置中创建空路由
在ng1应用中注入ng2路由,添加如下逻辑
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'); } }); }]);