zoukankan      html  css  js  c++  java
  • angular2 学习笔记 (Typescript

    更新 : 2019-07-11

    "emitDecoratorMetadata": true

    这个是 typescript 配合 metadata 的功能, 能过返回 类型, 比如 string, boolean 等. 

    不过也不是很准, 比如 string | null 这样它就 gg 了

    然后它还有一些 bug 

    https://github.com/Microsoft/TypeScript/issues/19563

    最近 ng 8 , 默认打包都会去 es6

    如果类型有循环引用, 就会遇到 bug 了, es5 的情况下是 ok 的

    感觉还是不要用这个为妙. 

    更新 : 2018-11-27

    { date: Date } 之前好像搞错了,这个是可以用 design:type 拿到的

    { date: Date | null } 任何类型一但配上了 | 就 design:type 就变成 object 了

    { arr : string[] } design:type = array

    design:type 是可以被我们覆盖的. e.g.:  Reflect.metadata('design:type', Date); 

    即使对象没有 property 反射依然管用, 
    design:type 本来是可以反射 property class 的 
    { person: Person } 但是循环引用就死掉了. 
    可以用 @Resource(forwardRef(() => Person)) 来处理. 勉强用。
    https://github.com/Microsoft/TypeScript/issues/19563
     

    更新 : 2017-04-07

    design.type 不可以反射出 Date 哦

    { date : Date } <-- 反射出来是 Object 

    { resource : A } vs { resource = new A() } vs  { resource : A = new A() }

    第一和第三 ok, 第二不行哦 会反射不出 class A 

    refer : https://www.npmjs.com/package/reflect-metadata 

    refer : https://www.typescriptlang.org/docs/handbook/decorators.html

    refer : http://blog.wolksoftware.com/decorators-metadata-reflection-in-typescript-from-novice-to-expert-part-4

    Attribute 和 reflection 在写 ng2 时我们也会常用到.

    熟悉静态语言的朋友应该都很习惯使用这 2 个东西了.

    我说的 Attribute 是站在 c# 的角度看的。

    前端更准确的说法是 decorator, annotations.

    Attribute 主要的目的就是让我们为属性等打上一个标签, 然后通过反射获取来做逻辑. 

    写标签就大的好处是可读性高. 

    目前反射是靠 reflect-metadata 来完成的. angular 也使用它哦

    example : 

    const RequiredSymbol = Symbol("RequiredSymbol");
    class Required
    {
    
    }
    function RequiredAttribute() {
        return Reflect.metadata(RequiredSymbol, new Required() );
    }

    使用

    class Person {
        @RequiredAttribute()
        @EmailAttribute()
        email: string  
    }

    我就是把他当 c# Attribute 来用的, 嘻嘻

    反射 

    let person = new Person();
    let keys = Reflect.getMetadataKeys(person, "email"); //获取所有的 Attribute
    let required: Required = Reflect.getMetadata(keys[1], person, "email"); //key[0] is "design:type" build in 的
    let required2: Required = Reflect.getMetadata(RequiredSymbol, person, "email"); //get by symbol

    注意 "design.type" 这个能获取到当前 property 的 type, 比如 String, Number, Product 

    这个 design.type 是自带的, 只要你使用了 decorator 就可以反射出类型, 很神奇哦!

    比如你写一个 decorator type

     @Type
     product : Product

    Type 什么都不做

    function Type(target : any, key : string) {
         
    }

    也是可以反射 "design.type" 出来

    我目前只用到 property 的, 其它的以后再说. 

    如果你不喜欢每次都写括弧 @xx(), 这样写也是 ok 的.

    let requriedSymbol = Symbol("required");
    let required = Reflect.metadata(requriedSymbol,null); //直接把生成好的方法存起来使用
    
    class Person {
        @required 
        name: string
    
        @required
        age: number
    }
    
    let p = new Person();
    let hasKey1 = Reflect.hasMetadata(requriedSymbol,p,"name"); 
    let hasKey2 = Reflect.hasMetadata(requriedSymbol,p,"age");

    一般上, 没有 import "reflect-metadata"; 的话, script 是照跑的. 不过有时候 typesciprt 会有 error ""

    我也不知道为什么 .. 

    目前的解决方法是 import "reflect-metadata";

    同时在 systemjs.config.js 里面加一个路径

    有朋友知道原因的话,请告诉我哦,万分感激. 

    运用在 class 上 

    export const someSymbol = Symbol("someSymbol");
    export function ComplexType(value : string) {  
        return Reflect.metadata(someSymbol, value);
    }
    
    @ComplexType("what ever")
    class Person
    {
        
    }
    let person = new Person();
    let result = Reflect.getMetadata(someSymbol,(person as Object).constructor); //使用的是 constructro 哦
    console.log(result); //what ever

    循环应用的问题 

    refer module 循环依赖 : http://es6.ruanyifeng.com/#docs/module

    由于 decorator 运行的早, 所以遇上 module 循环依赖时有时候会拿不到值

    // Type.ts
    export function Type(type : any) {    
        return Reflect.metadata("Type", type);
    }
    
    // product.model.ts
    import { Color } from "./color.model";
    import { Type } from "./Type";
    export class Product
    {
        @Type(Color)
        colors : Color[]
    } 
     
    // color.model.ts 
    import { Product } from "./product.model";
    import { Type } from "./Type";
    export class Color
    {
        @Type(Product)
        product : Product
    }
    
    // main.ts
    import { Color } from "./color.model";
    import { Product } from "./product.model";
    let product = new Product();
    let color = new Color();
    console.log( Reflect.getMetadata("Type",product,"colors" )); //undefined
    console.log( Reflect.getMetadata("Type",color,"product" )); //Product

    解决方法就是把全部都写成方法,需要调用的时候才去拿 

    export function Type(valueMethod : any) {  
        let cache : any = null; 
        let method = ()=>{
            if(cache) return cache;
            cache = valueMethod();
            return cache;
        } 
        return Reflect.metadata("Type", method);
    }
    
    @Type(() => Color)
    colors : Color[]
    
    @Type(() => Product)
    product : Product
    
    //调用方法获取
    console.log( Reflect.getMetadata("Type",product,"colors" )()  ); //color
    console.log( Reflect.getMetadata("Type",color,"product" )()  ); //Product
  • 相关阅读:
    linux ---用uniq实现文件的并集和交集
    vim的.vimrc文件设置
    CURL常用命令
    快速入门系列--MVC--03控制器和IOC应用
    linux下git安装
    openerp child_of操作符深度解析
    apache2 + virtualenv +djangocms
    django-cms安装
    pycharm3.4 下svn 项目checkout&配置
    在django项目外,使用django.db链接数据库(postgres)
  • 原文地址:https://www.cnblogs.com/keatkeat/p/6204646.html
Copyright © 2011-2022 走看看