美文网首页angular 2+ 点点滴滴我爱编程
angular中的那些可替换升级的技术总结

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

作者: 杨明明abc | 来源:发表于2018-06-07 12:28 被阅读20次

    可服务升级替换的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中的那些可替换升级的技术总结

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