美文网首页
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