angular中的那些可替换升级的技术总结

可服务升级替换的Service

import { Provider } from "@angular/core";

export abstract class Test {
    abstract console(): void;
}

export class TestDefault extends Test {
    console() {
        console.log('test default');
    }
}

export class MyTest extends Test {
    console() {
        console.log('my test');
    }
}

export const TestProvide: Provider = {
    provide: Test,
    useClass: TestDefault
};

export const MyTestProvide: Provider = {
    provide: Test,
    useClass: MyTest
};

这样可以选配某个provider

  • 模块中配置使用TestProvide
@NgModule({
  ...,
  providers: [
    TestProvide
  ]
})
  • 模块中配置使用MyTestProvide
@NgModule({
  ...,
  providers: [
    MyTestProvide
  ]
})

组件中使用TestProvide

@Component({
  ...,
  providers: [TestProvide]
})
export class AppComponent {
  constructor(public test: Test) {
    this.test.console();
  }
}

组件中使用TestProvide

@Component({
  ...,
  providers: [MyTestProvide]
})
export class AppComponent {
  constructor(public test: Test) {
    this.test.console();
  }
}

比如版本1我们开发了一个TestV1,
升级后可以替换TestV1->TestV2,仅仅改变配置文件即可!

可升级替换的组件

每个组件一个NgModule,NgModule提供替换Ref的static方法forRoot

// 定义组件属性和方法
export abstract class TestRef {
  title: string;
}

export class TestRefDefault {
  title: string = 'default';
}
// 默认
export const TestProvide: Provider[] = [
  {
    provide: TestRef,
    useClass: TestRefDefault
  }
];

@Component({
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.css']
})
export class TestComponent implements OnInit {
  // 绑定到ref属性
  @Input()
  set title(val: any) {
    this.ref.title = val;
  }
  constructor(
    public ref: TestRef
  ) { }
  ngOnInit() {
    console.log(this);
  }
}

小总结: 这样有一个弊端就是每个组件共享一个Ref,不能说是弊端,是有一定应用场景的,当所有组件共同操作一个Service时。

升级到factory,隔离Ref,而且可操控父级!

@NgModule({
    exports: [TestComponent],
    declarations: [TestComponent],
})
export class TestModule {
    public static forRoot(providers: Provider[] = TestProvide): ModuleWithProviders {
        return {
            ngModule: TestModule,
            providers: [providers]
        };
    }
}
@NgModule({
  imports: [
    CommonModule,
    TestModule.forRoot()
  ],
  declarations: [],
  exports: [TestModule],
  providers: [
    TestProvide
  ]
})
export class SharedModule { }
import { Provider } from '@angular/core';
import { Component, OnInit, Input, Optional, SkipSelf } from '@angular/core';
// 工厂方法
export abstract class TestRefFactory {
  abstract create(): TestRef;
}

// 定义组件属性和方法
export abstract class TestRef {
  title: string;
}
// 默认实现
export class TestRefDefault {
  title: string = 'default';
}
// 默认工厂
export class TestRefFactoryDefault extends TestRefFactory {
  create() {
    return new TestRefDefault();
  }
}
// 提供器
export const TestRefFactoryProvider: Provider[] = [{
  provide: TestRefFactory,
  useClass: TestRefFactoryDefault
}];

export function testFactory(factory: TestRefFactory) {
  return factory.create();
}

@Component({
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.css'],
  providers: [
    { provide: TestRef, useFactory: testFactory, deps: [TestRefFactory] }
  ]
})
export class TestComponent implements OnInit {
  // 绑定到ref属性
  @Input()
  set title(val: any) {
    this.ref.title += '-' + val;
  }
  constructor(
    public ref: TestRef,
    // 获取父亲的Ref
    @Optional()
    @SkipSelf()
    public fatherRef: TestRef
  ) { }
  ngOnInit() {
    console.log(this);
  }
}

可以获取父Ref,省去不必要的EventEmitter

ref中获取父ref

import { Provider } from '@angular/core';
import { Component, OnInit, Input, Optional, SkipSelf } from '@angular/core';
// 工厂方法
export abstract class TestRefFactory {
  abstract create(father: TestRef): TestRef;
}

// 定义组件属性和方法
export abstract class TestRef {
  title: string;
}
// 默认实现
export class TestRefDefault extends TestRef {
  title: string = 'default';
  constructor(
    public ref?: TestRef
  ) {
    super();
    console.log(this);
  }
}


// 默认工厂
export class TestRefFactoryDefault extends TestRefFactory {
  create(fatherRef?: TestRef) {
    return new TestRefDefault(fatherRef);
  }
}
// 提供器
export const TestRefFactoryProvider: Provider[] = [{
  provide: TestRefFactory,
  useClass: TestRefFactoryDefault
}];

export function testFactory(factory: TestRefFactory, fatherRef?: TestRef) {
  return factory.create(fatherRef);
}

export const testRefProvide = [
  {
    provide: TestRef,
    useFactory: testFactory,
    deps: [
      TestRefFactory,
      [new Optional(), new SkipSelf(), TestRef]
    ]
  }
];

@Component({
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.css'],
  providers: [
    testRefProvide
  ]
})
export class TestComponent implements OnInit {
  // 绑定到ref属性
  @Input()
  set title(val: any) {
    this.ref.title += '-' + val;
  }
  constructor(
    public ref: TestRef,
  ) { }

  ngOnInit() {
  }
}

你可能感兴趣的:(angular中的那些可替换升级的技术总结)