可服务升级替换的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() {
}
}