🆚Angular 学习之路

306 阅读2分钟

Angular

Angular 在国内的流行程度虽然不及 Vue, React, 但是 它代表着 Ioc 的思想,是很好的进入后端思想的路径。但是 Angular 的复杂程度是比其他框架都比较高的,理解器思想的必要性就更加重要。我们就从装饰器开始了解 Angular。

装饰器

Angular 源代码不向 Nestjs, 装饰器都是单独的文件夹表示出来。Angular 的源码显比较乱,如果阅读源码经验比较少的,往往很难把 Angular 搞的清除。 研究源码装饰器,它的目录在packages/core/src/metadata, 这里是和 refle t-metadata 有关的,我们知道装饰器,内部使用就是元数据和反射。但是 angular 中并没有使用提供库 reflect-metadata, 是自己实现的 metadata 部分和 reflect 部分。

NgModule 装饰器

  • packages/core/src/metadata/ng_module.ts
export const NgModule: NgModuleDecorator = makeDecorator(
    'NgModule', (ngModule: NgModule) => ngModule, undefined, undefined,
    (type: Type<any>, meta: NgModule) => SWITCH_COMPILE_NGMODULE(type, meta));

Angular 中的模块都是通过 makeDecorator 函数创建出来的. packages/core/src/util/decorators.ts 中包含了创建 NgModule 的方法。返回值是一个没有副作用的函数。

export function noSideEffects<T>(fn: () => T): T {
  return {toString: fn}.toString() as unknown as T;
}

本质就是 fn 的调用。

NgModule 的参数,接口

export interface NgModule {
    providers?: Provider[];
    declarations?: Array<Type<any>|any[]>;
    imports?: Array<Type<any>|ModuleWithProviders<{}>|any[]>;
    exports?: Array<Type<any>|any[]>;
    entryComponents?: Array<Type<any>|any[]>;
    bootstrap?: Array<Type<any>|any[]>;
    schemas?: Array<SchemaMetadata|any[]>;
    id?: string;
    jit?: true;
}

export interface NgModuleDecorator {
  (obj?: NgModule): TypeDecorator;
  new (obj?: NgModule): NgModule;
}

export type Provider = TypeProvider | ValueProvider | ClassProvider | ConstructorProvider |
    ExistingProvider | FactoryProvider | any[];

export interface TypeProvider extends Type<any> {}
export interface Type<T> extends Function { new (...args: any[]): T; }

export interface ValueProvider extends ValueSansProvider {
  provide: any;
  multi?: boolean;
}
export interface ValueSansProvider {
  useValue: any;
}

export interface ClassProvider extends ClassSansProvider {
  provide: any;
  multi?: boolean;
}
export interface ClassSansProvider {
  useClass: Type<any>;
}

export interface ConstructorProvider extends ConstructorSansProvider {
  provide: Type<any>;
  multi?: boolean;
}
export interface ConstructorSansProvider {
  deps?: any[];
}

export interface ExistingProvider extends ExistingSansProvider {
  provide: any;
  multi?: boolean;
}
export interface ExistingSansProvider {
  useExisting: any;
}

export interface FactoryProvider extends FactorySansProvider {
  provide: any;
  multi?: boolean;
}
export interface FactorySansProvider {
  useFactory: Function;
  deps?: any[];
}

Component 装饰器

组件的 decorator 也是通过 makeDecorator 创建出来的。组件装饰器用于装饰一个 Angular 组件。

// 创建组件装饰器
export const Component: ComponentDecorator = makeDecorator(
    'Component', (c: Component = {}) => ({changeDetection: ChangeDetectionStrategy.Default, ...c}),
    Directive, undefined,
    (type: Type<any>, meta: Component) => SWITCH_COMPILE_COMPONENT(type, meta));
    
// 接口ComponentDecorator
export interface ComponentDecorator {
    (obj: Component): TypeDecorator;
    new (obj: Component): Component;
}

// Component 接口是继承指令接口
export interface Component extends Directive {
    changeDetection?: ChangeDetectionStrategy;
    viewProviders?: Provider[];
    moduleId?: string;
    templateUrl?: string;
    template?: string;
    styleUrls?: string[];
    styles?: string[];
    animations?: any[];
    encapsulation?: ViewEncapsulation;
    interpolation?: [string, string];
    entryComponents?: Array<Type<any>|any[]>;
    preserveWhitespaces?: boolean;
}