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
  • 相关阅读:
    leetcode 576. Out of Boundary Paths 、688. Knight Probability in Chessboard
    leetcode 129. Sum Root to Leaf Numbers
    leetcode 542. 01 Matrix 、663. Walls and Gates(lintcode) 、773. Sliding Puzzle 、803. Shortest Distance from All Buildings
    leetcode 402. Remove K Digits 、321. Create Maximum Number
    leetcode 139. Word Break 、140. Word Break II
    leetcode 329. Longest Increasing Path in a Matrix
    leetcode 334. Increasing Triplet Subsequence
    leetcode 403. Frog Jump
    android中webView加载H5,JS不能调用问题的解决
    通过nginx中转获取不到IP的问题解决
  • 原文地址:https://www.cnblogs.com/keatkeat/p/6204646.html
Copyright © 2011-2022 走看看