美文网首页
ng1 与 ng9 混合应用简单示例

ng1 与 ng9 混合应用简单示例

作者: niccky | 来源:发表于2020-09-01 22:45 被阅读0次

    本示例主要做一下几个事情:

    • AppModule 启动 ng1 应用模块
    • 定义一个 ng1 组件并升级给 ng9 使用
    • 定义一个 ng9 组件并降级给 ng1 使用
    • 定义一个 ng9 服务并降级给 ng1 使用
    • 演示三种数据绑定方式: @, <, =
    • ng9 中获取 ng1 定义的 $rootScope 和其他服务

    引入 ng9 依赖包

    import {
        NgModule,
        Directive,
        Component,
        ElementRef,
        Injector,
        Input,
        EventEmitter,
        Output,
        Injectable,
      } from '@angular/core';
      
    import { BrowserModule } from '@angular/platform-browser';
    

    引入 ng1 依赖包

      import * as angular from 'angular@1.7.5';
      import {
        UpgradeModule,
        downgradeComponent,
        UpgradeComponent,
        downgradeInjectable,
      } from '@angular/upgrade/static';
    

    定义 ng9 示例服务

      @Injectable()
      export class UserService {
        getUser() {
          return Promise.resolve({
            name: 'mock name',
            id: 1,
            addr: 'shenzhen',
          });
        }
      }
    

    定义 ng1 组件

      const ng1Component: angular.IComponent = {
        template: `
          Hello, Angularjs!
          <p>{{$ctrl.appName}}</p>
          <p>{{$ctrl.appId}}</p>
          <p>{{$ctrl.model}}</p>
          <p>{{$ctrl.relation}}</p>
          <input ng-model="$ctrl.desc" />
          value: {{$ctrl.desc}}
        `,
        bindings: {
          // @ 绑定
          appName: '@appName',
          appId: '@',
      
          // < 绑定
          model: '<model',
          relation: '<',
      
          // = 绑定
          desc: '=desc',
        },
        controller: function (user) {
          // user 注入 经过 downgradeInjectable(...) 过后的服务
          user.getUser().then((data) => {
            console.log('ng1', data); // 输出服务定义的数据
          });
        },
      };
    

    升级 ng1 组件给 ng9 使用

    @Directive({ selector: 'ng1' })
    export class Ng1ComponentFacade extends UpgradeComponent {
      // @ 绑定
      @Input() appName!: string;
      @Input() appId: any;
    
      // < 绑定
      @Input() model: any;
      @Input() relation: any;
    
      // & 绑定
      @Input() desc: string;
      @Output() descChange: EventEmitter<any>;
    
      constructor(elementRef: ElementRef, injector: Injector) {
        super('ng1', elementRef, injector);
      }
    }
    

    定义一个 ng9 组件

     @Component({
       selector: 'ng9',
       template: `ng9 component <br />
         <ng1
           [appName]="appName"
           [(desc)]="desc"
           [appId]="appId"
           model="{{ model }}"
           [relation]="relation"
         ></ng1>
         <p>desc: {{ desc }}</p> `,
     })
     export class Ng9Component {
       appName: string = 'demo name';
       appId: string = 'demo id';
       model: string = 'demo model';
       relation: string = 'demo relation';
       desc: string = 'demo desc!!!';
     
       constructor(private user: UserService) {}
     
       ngOnInit() {
         this.user.getUser().then((user) => {
           console.log('ng9', user);
         });
    
       // 获取 ng1  服务
       angular.element(document.body).injector().get('ng1Service');
       // 获取 ng1 的 $rootScope
       angular.element(document.body).injector().get('$rootScope');
       }
     }
    

    定义一个 ng1 启动模块

    const ng1App = angular
      .module('ng1Module', [])
      .factory('user', downgradeInjectable(UserService)) // 降级 ng9 服务给 ng1 使用
      .component('ng1', ng1Component) // 定义一个 ng1 组件
      .directive('ng9', downgradeComponent({ component: Ng9Component })); // 降级 ng9 组件给 ng1 使用
    
    @NgModule({
      declarations: [AppComponent, Ng1ComponentFacade, Ng9Component], // 配置 Ng1ComponentFacade, Ng9Component
      imports: [BrowserModule, UpgradeModule], // 配置 UpgradeModule
      providers: [UserService], // 配置 provider
    })
    export class AppModule /*这里是 ng9 的启动模块*/ {
      constructor(private upgrade: UpgradeModule) {} // 注入 UpgradeModule
    
      ngDoBootstrap() {
        // 启动 ng1 应用
        this.upgrade.bootstrap(document.body, [ng1App.name]);
      }
    }
    

    以上步骤操作完成后,就可以启动应用了

    注意: @NgModule({...}) 里面不需要配置 bootstrap: [AppComponent]

    完整代码

    import {
      NgModule,
      Directive,
      Component,
      ElementRef,
      Injector,
      Input,
      EventEmitter,
      Output,
      Injectable,
      Inject,
    } from '@angular/core';
    
    import { BrowserModule } from '@angular/platform-browser';
    import * as angular from 'angular';
    
    // @angular/upgrade/static
    import {
      UpgradeModule,
      downgradeComponent,
      UpgradeComponent,
      downgradeInjectable,
    } from '@angular/upgrade/static';
    
    import { AppComponent } from './app.component';
    
    // 定义 ng9 示例服务
    @Injectable()
    export class UserService {
      getUser() {
        return Promise.resolve({
          name: 'mock name',
          id: 1,
          addr: 'shenzhen',
        });
      }
    }
    
    // 定义 ng1 组件
    const ng1Component: angular.IComponent = {
      template: `
        Hello, Angularjs!
        <p>{{$ctrl.appName}}</p>
        <p>{{$ctrl.appId}}</p>
        <p>{{$ctrl.model}}</p>
        <p>{{$ctrl.relation}}</p>
        <input ng-model="$ctrl.desc" />
        value: {{$ctrl.desc}}
      `,
      bindings: {
        // @ 绑定
        appName: '@appName',
        appId: '@',
    
        // < 绑定
        model: '<model',
        relation: '<',
    
        // = 绑定
        desc: '=desc',
      },
      controller: function (user) {
        // user 注入 经过 downgradeInjectable(...) 过后的服务
        user.getUser().then((data) => {
          console.log('ng1', data); // 输出服务定义的数据
        });
      },
    };
    
    // 升级 ng1 组件给 ng9 使用
    @Directive({ selector: 'ng1' })
    export class Ng1ComponentFacade extends UpgradeComponent {
      // @ 绑定
      @Input() appName!: string;
      @Input() appId: any;
    
      // < 绑定
      @Input() model: any;
      @Input() relation: any;
    
      // & 绑定
      @Input() desc: string;
      @Output() descChange: EventEmitter<any>;
    
      constructor(elementRef: ElementRef, injector: Injector) {
        super('ng1', elementRef, injector);
      }
    }
    
    // Define `Ng9Component`
    @Component({
      selector: 'ng9',
      template: `ng9 component <br />
        <ng1
          [appName]="appName"
          [(desc)]="desc"
          [appId]="appId"
          model="{{ model }}"
          [relation]="relation"
        ></ng1>
        <p>desc: {{ desc }}</p> `,
    })
    export class Ng9Component {
      appName: string = 'demo name';
      appId: string = 'demo id';
      model: string = 'demo model';
      relation: string = 'demo relation';
      desc: string = 'demo desc!!!';
    
      constructor(
        private user: UserService,
        private injector: Injector // @Inject('$inject') private $inject: any
      ) {}
    
      ngOnInit() {
        this.user.getUser().then((user) => {
          console.log('ng9', user);
        });
    
        // 获取 ng1  服务
        angular.element(document.body).injector().get('ng1Service');
    
        // 获取 ng1 的 $rootScope
        angular.element(document.body).injector().get('$rootScope');
      }
    }
    
    // 定义一个 ng1 启动模块
    const ng1App = angular
      .module('ng1Module', [])
      .factory('ng1Service', function () {
        return {
          data: {
            name: 'ng1 service',
          },
        };
      })
      .factory('user', downgradeInjectable(UserService)) // 降级 ng9 服务给 ng1 使用
      .component('ng1', ng1Component) // 定义一个 ng1 组件
      .directive('ng9', downgradeComponent({ component: Ng9Component })); // 降级 ng9 组件给 ng1 使用
    
    @NgModule({
      declarations: [AppComponent, Ng1ComponentFacade, Ng9Component], // 配置 Ng1ComponentFacade, Ng9Component
      imports: [BrowserModule, UpgradeModule], // 配置 UpgradeModule
      providers: [UserService], // 配置 provider
    })
    export class AppModule /*这里是 ng9 的启动模块*/ {
      constructor(private upgrade: UpgradeModule) {} // 注入 UpgradeModule
    
      ngDoBootstrap() {
        // 启动 ng1 应用
        this.upgrade.bootstrap(document.body, [ng1App.name]);
      }
    }
    

    package.json

    {
        "name": "demo",
        "version": "0.0.0",
        "scripts": {
          "ng": "ng",
          "start": "ng serve",
          "build": "ng build",
          "test": "ng test",
          "lint": "ng lint",
          "e2e": "ng e2e"
        },
        "private": true,
        "dependencies": {
          "@angular/animations": "~10.0.6",
          "@angular/common": "~10.0.6",
          "@angular/compiler": "~10.0.6",
          "@angular/core": "~10.0.6",
          "@angular/forms": "~10.0.6",
          "@angular/platform-browser": "~10.0.6",
          "@angular/platform-browser-dynamic": "~10.0.6",
          "@angular/router": "~10.0.6",
          "@angular/upgrade": "^10.0.14",
          "angular": "^1.7.5",
          "rxjs": "~6.5.5",
          "tslib": "^2.0.0",
          "zone.js": "~0.10.3"
        },
        "devDependencies": {
          "@angular-devkit/build-angular": "~0.1000.5",
          "@angular/cli": "~10.0.5",
          "@angular/compiler-cli": "~10.0.6",
          "@types/jasmine": "~3.5.0",
          "@types/jasminewd2": "~2.0.3",
          "@types/node": "^12.11.1",
          "codelyzer": "^6.0.0",
          "jasmine-core": "~3.5.0",
          "jasmine-spec-reporter": "~5.0.0",
          "karma": "~5.0.0",
          "karma-chrome-launcher": "~3.1.0",
          "karma-coverage-istanbul-reporter": "~3.0.2",
          "karma-jasmine": "~3.3.0",
          "karma-jasmine-html-reporter": "^1.5.0",
          "protractor": "~7.0.0",
          "ts-node": "~8.3.0",
          "tslint": "~6.1.0",
          "typescript": "~3.9.5"
        }
      }
      
    

    相关文章

      网友评论

          本文标题:ng1 与 ng9 混合应用简单示例

          本文链接:https://www.haomeiwen.com/subject/afmbsktx.html