自举 Angular 2 + Angular 1 使用 downgradeComponent 时混合应用程序未加载
Bootstrapped Angular 2 + Angular 1 Hybrid App not loading when using downgradeComponent
我有一个 Angular 1 应用程序,我已按照官方 Angular 教程 (https://angular.io/docs/ts/latest/guide/upgrade.html) 中的说明引导混合 1+2 应用程序。我已经准备好所有代码和 运行 应用程序,但绝对没有任何反应。它只是转到根 URL,我只得到 index.html
中任何内容的样式和视图。然而,主要 <div ng-view>
永远不会通过 $routeProvider
和 app.ts
更新。至少这似乎是正在发生的事情。有 零 个错误。这是我目前所拥有的:
main.ts(通过 SystemJS 加载)
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { UpgradeModule } from '@angular/upgrade/static';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
upgrade.bootstrap(document.body, ['MyA1App']);
});
上述混合 bootstrap 代码的一个注释 - 据我所知,它 是 工作。如果我将 Angular1 应用程序名称更改为 blahblah
,我会在浏览器中收到一大堆错误。此代码 可以 找到 app.ts
中定义的 MyA1App
Angular1 模块,并且能够 bootstrap 它。
index.html:
<div class="main-content" ng-view=""></div>
<!-- Configure SystemJS (bootstrap Angular 2 app) -->
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
<!-- Old Angular 1 bootstrap method -->
<!--<script>
angular.bootstrap(document.body, ['MyA1App']);
</script>-->
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { UpgradeModule } from '@angular/upgrade/static'; //To bootstrap a hybrid application, we need to import UpgradeModule in our AppModule, and override it's bootstrap method:
@NgModule({
imports: [BrowserModule, UpgradeModule ],
})
export class AppModule {
ngDoBootstrap() {}
}
import { downgradeComponent } from '@angular/upgrade/static';
angular.module('MyA1App', [])
.directive(
'contactList',
downgradeComponent({ component: ContactListComponent }) as angular.IDirectiveFactory
);
app.ts(来自 Angular 1,它定义了模块和路由 - 这应该仍在使用和使用)
module MyApp {
'use strict';
export var App: ng.IModule = angular.module('MyA1App', ['ngRoute', 'ngResource', 'highcharts-ng', 'ui.bootstrap']);
// register work which needs to be performed on module loading
App.config([
'$routeProvider', '$httpProvider',
($routeProvider: ng.route.IRouteProvider, $httpProvider: ng.IHttpProvider) => {
$routeProvider
.when('/landing',
{
controller: MyApp.Controllers.LandingCtrl,
templateUrl: '/app/angular1x/partials/landing.html'
})
.when('/registration',
{
controller: MyApp.Controllers.RegistrationCtrl,
controllerAs: 'vm',
templateUrl: '/app/angular1x/partials/registration.html'
})
.otherwise({
redirectTo: '/landing'
});
}
]);
}
下面是问题的概述:
- 通过在
index.html
中调用的 systemjs
引导至 Angular2 main.ts
(显示成功 - 无错误)
- 我可以在 Angular1 个控制器、Landing 等中放置断点,然后查看正在定义和加载的控制器。但没有其他事情发生!没有错误或任何东西。
ng-view
指令永远不会通过路由更新。在主页上检查后,它看起来像:<div class="main-content" ng-view=""></div>
- 没有任何 JS 错误
- 如果我返回并在
index.html
中使用原始 A1 bootstrap,它的工作原理与使用 systemjs
加载 A2 和 bootstrap A1 作为混合体相反。
我在这里做错了什么,原来的 Angular1
应用似乎可以加载并且 bootstrap 很好,但实际上什么也没做?
更新:
我已经在 app.module.ts
中找到如下违规代码:
import { downgradeComponent } from '@angular/upgrade/static';
angular.module('MyA1App', [])
.directive(
'contactList',
downgradeComponent({ component: ContactListComponent }) as angular.IDirectiveFactory
);
这不是路由(这是一个转移注意力的问题)。如果我删除上面的代码,整个 Angular1
应用程序将 bootstrap 加载。我在上面的代码中做了什么可能会导致所有内容停止加载,但不会产生任何 JavaScript
错误?
好吧,我已经深入了解了这个问题,但由于遵循 UPGRADING FROM 1.X 教程,我浪费了这么长的时间,这令人失望。在教程中,它显示了这个 exact 示例代码,通过 Angular 1
模块将其注册为 directive
来降级 Angular 2
组件:
angular.module('heroApp', [])
.directive(
'heroDetail',
downgradeComponent({component: HeroDetailComponent}) as angular.IDirectiveFactory
);
注意到模块名称后的空括号 []
了吗? 就是问题所在。它让我陷入了疯狂的追逐,因为当我得到直接来自教程的内容时,我开始收到关于我的控制器的错误 Angular1
not being defined。由于其中很多内容仍然是新鲜的,我开始了疯狂的追逐,剥离了我的 A1
应用程序的部分内容,试图让它们工作,认为它们与 A2
不兼容。直到我在同一个教程中读到,"The existing Angular 1 code works as before and you're ready to run Angular 2 code" 这让我开始消除 A2 bootstrap 代码中的某些内容是错误的,最终括号导致没有加载。
我的 OP 注意到我没有收到任何错误。这是因为我已经剥离了很多 A1
代码试图让事情正常进行并到达应用程序加载但没有显示任何东西的地步并认为这是一个路由问题。
我的工作代码如下:
angular.module('MyA1App')
.directive('contactList', downgradeComponent({ component: ContactListComponent }) as angular.IDirectiveFactory);
我有两个建议:
在您的 index.html 中,将 <div class="main-content" ng-view=""></div>
更改为 <div class="main-content" ui-view></div>
。
从索引中删除 <div class="main-content" ng-view=""></div>
并添加 <root-cmp></root-cmp>
像这样更新您的 app.module.ts:
@Component({
selector: 'root-cmp',
template: '<div class="main-content" ui-view></div>'
})
export class RootCmp {
}
@NgModule({
imports: [
BrowserModule,
UpgradeModule
],
bootstrap: [RootCmp],
declarations: [
RootCmp
],
providers: [],
entryComponents: [
RootCmp
]
})
export class Ng2Module {
ngDoBootstrap() {
}
}
我有一个 Angular 1 应用程序,我已按照官方 Angular 教程 (https://angular.io/docs/ts/latest/guide/upgrade.html) 中的说明引导混合 1+2 应用程序。我已经准备好所有代码和 运行 应用程序,但绝对没有任何反应。它只是转到根 URL,我只得到 index.html
中任何内容的样式和视图。然而,主要 <div ng-view>
永远不会通过 $routeProvider
和 app.ts
更新。至少这似乎是正在发生的事情。有 零 个错误。这是我目前所拥有的:
main.ts(通过 SystemJS 加载)
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { UpgradeModule } from '@angular/upgrade/static';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
upgrade.bootstrap(document.body, ['MyA1App']);
});
上述混合 bootstrap 代码的一个注释 - 据我所知,它 是 工作。如果我将 Angular1 应用程序名称更改为 blahblah
,我会在浏览器中收到一大堆错误。此代码 可以 找到 app.ts
中定义的 MyA1App
Angular1 模块,并且能够 bootstrap 它。
index.html:
<div class="main-content" ng-view=""></div>
<!-- Configure SystemJS (bootstrap Angular 2 app) -->
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
<!-- Old Angular 1 bootstrap method -->
<!--<script>
angular.bootstrap(document.body, ['MyA1App']);
</script>-->
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { UpgradeModule } from '@angular/upgrade/static'; //To bootstrap a hybrid application, we need to import UpgradeModule in our AppModule, and override it's bootstrap method:
@NgModule({
imports: [BrowserModule, UpgradeModule ],
})
export class AppModule {
ngDoBootstrap() {}
}
import { downgradeComponent } from '@angular/upgrade/static';
angular.module('MyA1App', [])
.directive(
'contactList',
downgradeComponent({ component: ContactListComponent }) as angular.IDirectiveFactory
);
app.ts(来自 Angular 1,它定义了模块和路由 - 这应该仍在使用和使用)
module MyApp {
'use strict';
export var App: ng.IModule = angular.module('MyA1App', ['ngRoute', 'ngResource', 'highcharts-ng', 'ui.bootstrap']);
// register work which needs to be performed on module loading
App.config([
'$routeProvider', '$httpProvider',
($routeProvider: ng.route.IRouteProvider, $httpProvider: ng.IHttpProvider) => {
$routeProvider
.when('/landing',
{
controller: MyApp.Controllers.LandingCtrl,
templateUrl: '/app/angular1x/partials/landing.html'
})
.when('/registration',
{
controller: MyApp.Controllers.RegistrationCtrl,
controllerAs: 'vm',
templateUrl: '/app/angular1x/partials/registration.html'
})
.otherwise({
redirectTo: '/landing'
});
}
]);
}
下面是问题的概述:
- 通过在
index.html
中调用的systemjs
引导至 Angular2main.ts
(显示成功 - 无错误) - 我可以在 Angular1 个控制器、Landing 等中放置断点,然后查看正在定义和加载的控制器。但没有其他事情发生!没有错误或任何东西。
ng-view
指令永远不会通过路由更新。在主页上检查后,它看起来像:<div class="main-content" ng-view=""></div>
- 没有任何 JS 错误
- 如果我返回并在
index.html
中使用原始 A1 bootstrap,它的工作原理与使用systemjs
加载 A2 和 bootstrap A1 作为混合体相反。
我在这里做错了什么,原来的 Angular1
应用似乎可以加载并且 bootstrap 很好,但实际上什么也没做?
更新:
我已经在 app.module.ts
中找到如下违规代码:
import { downgradeComponent } from '@angular/upgrade/static';
angular.module('MyA1App', [])
.directive(
'contactList',
downgradeComponent({ component: ContactListComponent }) as angular.IDirectiveFactory
);
这不是路由(这是一个转移注意力的问题)。如果我删除上面的代码,整个 Angular1
应用程序将 bootstrap 加载。我在上面的代码中做了什么可能会导致所有内容停止加载,但不会产生任何 JavaScript
错误?
好吧,我已经深入了解了这个问题,但由于遵循 UPGRADING FROM 1.X 教程,我浪费了这么长的时间,这令人失望。在教程中,它显示了这个 exact 示例代码,通过 Angular 1
模块将其注册为 directive
来降级 Angular 2
组件:
angular.module('heroApp', [])
.directive(
'heroDetail',
downgradeComponent({component: HeroDetailComponent}) as angular.IDirectiveFactory
);
注意到模块名称后的空括号 []
了吗? 就是问题所在。它让我陷入了疯狂的追逐,因为当我得到直接来自教程的内容时,我开始收到关于我的控制器的错误 Angular1
not being defined。由于其中很多内容仍然是新鲜的,我开始了疯狂的追逐,剥离了我的 A1
应用程序的部分内容,试图让它们工作,认为它们与 A2
不兼容。直到我在同一个教程中读到,"The existing Angular 1 code works as before and you're ready to run Angular 2 code" 这让我开始消除 A2 bootstrap 代码中的某些内容是错误的,最终括号导致没有加载。
我的 OP 注意到我没有收到任何错误。这是因为我已经剥离了很多 A1
代码试图让事情正常进行并到达应用程序加载但没有显示任何东西的地步并认为这是一个路由问题。
我的工作代码如下:
angular.module('MyA1App')
.directive('contactList', downgradeComponent({ component: ContactListComponent }) as angular.IDirectiveFactory);
我有两个建议:
在您的 index.html 中,将
<div class="main-content" ng-view=""></div>
更改为<div class="main-content" ui-view></div>
。从索引中删除
<div class="main-content" ng-view=""></div>
并添加<root-cmp></root-cmp>
像这样更新您的 app.module.ts:
@Component({
selector: 'root-cmp',
template: '<div class="main-content" ui-view></div>'
})
export class RootCmp {
}
@NgModule({
imports: [
BrowserModule,
UpgradeModule
],
bootstrap: [RootCmp],
declarations: [
RootCmp
],
providers: [],
entryComponents: [
RootCmp
]
})
export class Ng2Module {
ngDoBootstrap() {
}
}