この記事では、主に angularjs から angularjs2+ への angularjs のアップグレードについて紹介します。それでは、この記事を一緒に読んでみましょう
数か月かけてアップグレードするために時間をかけて取り組んだ 2 つのプロジェクトと 1 つのプロジェクトをまとめると、 UpgradeModule が使用されます。もう 1 つは DowngradeModule です: (ng1->AngularJS; ng2+->Angular2+) 詳細については、公式ドキュメントを参照してください: https://angular.io/guide/upgrade
使用する必要のある typescript の長所、短所、使用方法についてはここでは説明しません。import { NgModule } from '@angular/core'; import { UpgradeModule } from '@angular/upgrade/static'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => { const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; upgrade.bootstrap(document.body, ['carepilot'], { strictDi: true }); });
import { NgModule, forwardRef } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { UpgradeModule } from '@angular/upgrade/static'; @NgModule({ imports: [ BrowserModule, UpgradeModule ], bootstrap: [] }) export class AppModule { ngDoBootstrap() {} }
{ "compileOnSave": false, "compilerOptions": { "sourceMap": true, "declaration": false, "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, "noImplicitAny": true, "target": "es5", "typeRoots": [ "node_modules/@types" ], "lib": [ "es2015", "dom" ] }, "exclude": [ "node_modules" ] }
/** * System configuration for Angular samples * Adjust as necessary for your application needs. */ (function (global) { System.config({ paths: { 'npm:': 'node_modules/' }, map: { app: 'app', '@angular/core': 'npm:@angular/core/bundles/core.umd.js', '@angular/common': 'npm:@angular/common/bundles/common.umd.js', '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', '@angular/http': 'npm:@angular/http/bundles/http.umd.js', '@angular/router': 'npm:@angular/router/bundles/router.umd.js', '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js', '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', 'rxjs': 'npm:rxjs' }, packages: { app: { defaultExtension: 'js' }, rxjs: { defaultExtension: 'js', format: 'cjs' } } }); })(this);
<script></script> <script></script> <script></script> <script></script> <!-- inject:js --> <!-- endinject --> <script> System.import('main.js') .then(null, console.error.bind(console)); </script>
研究) import {
Component,
Inject
} from '@angular/core';
import { Broadcaster } from '../../services/broadcaster';
@Component({
selector: 'about',
templateUrl: './about.component.html'
})
export class AboutComponent {
constructor(private broadcaster: Broadcaster) {
}
print(): void {
this.broadcaster.broadcast('printContents', 'printable');
}
}
angular.module('interestApp') .directive('pinControls', upgradeAdapter.downgradeNg2Component(PinControlsComponent));
config.js でルーティングを更新します (前提として) ui-state を使用します):
.state('add', { template: "<add-pin></add-pin>", url: '/add'
* 同じ問題ですが、一部のコントローラーをアップグレードした後は、以前のサービスに依存する必要があります。現時点では、 で使用できるように ng1 のサービスを ng2+ に一時的にアップグレードする必要があります。 ng2+ のコンポーネントでは、これはアップグレード プロセス中にのみ発生しました。現時点では、対応するライブラリの定義を http://definelytyped.org/docs で見つけることができます。 /angular-ui--angular-ui-router/modules/ng.html
* アップグレード後、最も使いにくいのは $scope と $rootscope です。ng1 では、グローバル ルートスコープは非常に使いやすかったのですが、 ng2+ ではキャンセルされました。以前のルートスコープを置き換えるサービスを定義する必要があります。現在のコンポーネントを直接使用することはできません。値をバインドするには @input と @output を使用します。前の =,> 値の受け渡しプロセスに対応します
* ルートを定義するには ng2+ Router を使用します : もちろん、ui-route @ui-route のアップグレードされたバージョンを引き続き使用することもできます
const AppRouting: Routes = [ { path: 'app', component: DashboardComponent, canLoad: [AuthGuard], canActivate: [AuthGuard], data: { pageTitle: 'Dashboard' }];
* (新しいメソッドの使用、習慣の変更、一部の ng1 ライブラリがメンテナンスされていない、または ng2+ にアップグレードされていないことが判明しました。代わりのものを見つけるか、自分で作成してください
)、ついに ng1 のすべてをアップグレードし、レガシーとサポートを削除する時が来ました。 ng1 のプログラムを作成し、それを完全な ng2+ プログラムに変換します。
** upgrademodule:
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; platformBrowserDynamic().bootstrapModule(AppModule);
** すべてのアップグレード モジュールとダウングレード モジュールを削除します。
** 初期ルートをロードするための appcomponent を追加します (ここでは、続行する場合は ng2+ デフォルト ルートを使用することを想定しています。 ui -route を使用し、そのまま ui-view を使用してください)
import { Component } from '@angular/core'; import { Router, ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-root', template: ` <p> <router-outlet></router-outlet> </p> ` }) export class AppComponent { constructor(private route: Router) { let loc = window.location.pathname.toString(); if (loc == '/login' || loc == '/') { this.route.navigate(['login']); } } }
2. ダウングレード: 公式の紹介文は金と同じくらい貴重ですが、これを初めて試す人にとっては非常に理解しにくいです。
原理:downgrade是不改变原来的ng1程序,新建一个ng2+程序,然后把这个程序做成一个模块,直接注入到ng1里头,这样会避免一些额外的change事件,从而避免了不必要的消息循环,这样来提升性能。
用下面的5步升级到ng2+:
第一步:写一个新的ng2+程序,然后注入到ng1里头:
main.ts: (XXXXXX替换成你的ng1的app的名字就行了)
import { NgModule, forwardRef, StaticProvider } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; import { downgradeModule, downgradeComponent, setAngularLib } from '@angular/upgrade/static'; declare const angular: any; declare const window: any; const bootstrapFn = (extraProviders: StaticProvider[]) => { const platformRef = platformBrowserDynamic(extraProviders); return platformRef.bootstrapModule(AppModule); }; const downgradedModule = downgradeModule(bootstrapFn); angular.module('XXXXXX.ng2', [ downgradedModule ]); angular.module('XXXXXX.ng2').directive('template', downgradeComponent({ component: template}));
* app.js (就这里麻烦,试了一天才试出来,这么注入,然后加载)
(function() { angular.module('XXXXXXX', [ // all the old modules 'XXXXXXX.ng2' ]); // eslint-disable-next-line if (window.ignoreNg2ForTest) { // temporary not load ng2 module in karma test fetchData().then(bootstrapApplication); } else { // normal hybrid entrance loadMain().then(fetchData).then(bootstrapApplication); } function loadMain() { return System.import('main'); // load main.ts } function fetchData() { // old logic } function bootstrapApplication() { angular.element(document).ready(function() { angular.bootstrap(document, ['XXXXXXXX'], { strictDi: true }); // bootstrap app with ng1 }); } }());
* 同样,在index.html里加入一些依赖(升级完都可以删)
<script></script> <script></script> <script></script> <script></script>
* 手动拷一些依赖到dest 文件夹:(我们用的gulp)
pipes.builtAngularVendorScriptsDev = function() { return gulp.src([ './node_modules/core-js/client/shim.min.js', ............ ], {base: './node_modules'}) .pipe(gulp.dest('dist.dev/node_modules')); };
* JSPM: 不用这东西的话release 里头的客户端有近百M,会疯的,虽然这个东西也bug重重,临时用用还是可以的。用它以后release的客户端代码只有十几M,可以接受了。
gulp.task('build-jspm-prod', ['hybrid-tsbuild'], function() { return jspm({ config: './client/systemjs.config.js', bundleOptions: { minify: true, mangle: false }, bundleSfx: true, bundles: [ { src: paths.tsOutput + '/*', dst: 'main.js' } ] }).pipe(gulp.dest('dist.prod')); });
第二步:升级一个个的controller/service/pipe/directive等等,这个过程相当痛苦,原来代码的耦合,莫名其妙的event emit和不知道在哪儿的event handler。全局的rootscope遍地都是,牵一发动全身。自己解耦吧,没什么好办法。
第三步:升级路由,这个虽然没有上一步那么煎熬,也很头疼,很多地方都要改,
* 如果用route的话参见上面upgrademodule里的例子就好了;
* 如果使用@ui-route的话,state现在需要这么定义:(abstract我还没有研究出来有什么用)
export const registerState = { parent: 'app', name: 'register', url: '/register/{activationCode}', component: RegisterComponent, data: { pageTitle: 'Register' } };
第四步:删除ng1的东西;
第五步:使用angular-cli管理依赖:
* 参照上面upgrademodule对应的步骤就好;
* 这时候可以删除JSPM了,这东西和SystemJS都是定时炸弹,bug重重啊,目前angular-cli比较稳定;
到这里,应该你的程序已经升级到了ng2+,目前是ng5,建议升级过程中把anglar相应的版本写死,这东西更新太快,你随着它升随时出现已有的包不兼容,很头疼,我们暂时定格在5.0。
我是升级完了站着说话不腰疼,上面的东西只能帮有需要的朋友节约一点点时间,最大的时间消耗在升级controller和解耦的过程中。那里如果有什么问题可以在下面留言,能帮上的话尽量帮大家省省时间。
备注一:替换规则。
ng-bind-html [innerHTML]
ng-model [(ngModel)] // 这个和ng1的双向绑定基本一个意思
ng-class [ngClass]
ng-disabled [disabled]
ng-click (click)
ng-if *ngIf
ng-repeat *ngFor // E.g. *ngFor="let task of currentChecklist.open; let i = index;"
ng-show *ngIf
ng-src [src]
ng-hide *ngIf
ng-submit (ngSubmit)
ng-style [ngStyle]
备注二:可能遇到的问题
JS:
消息处理:ng2+里没有了scope继承,所以自己定义全局的消息处理是必要的;
HTML模板:
ディレクティブの競合: 定義された名前を ng1 で
AngularJS ユーザー マニュアル にアクセスして学習してください)。ご質問がある場合は、以下にメッセージを残してください。
以上がAngularJS を Angular2+ にアップグレードするにはどうすればよいですか? angularjs アップグレードの紹介例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。