zoukankan      html  css  js  c++  java
  • angular2 学习笔记 ( 4.0 初探 )

    目前是 4.0.0-rc.2. 

    刚好有个小项目要开发,就直接拿它来试水啦.

    更新 cli 到最新版, 创建项目, 然后 follow https://github.com/angular/angular/blob/master/CHANGELOG.md 升级去 4.0

    遇到一个 error https://github.com/angular/angular-cli/issues/5131

    更新 typescript 就可以了.

    一些新功能和 break change 

    1. template 替换成 ng-template 了

    <template #loading>Loading...</template> <!--弃用了-->
    <ng-template #loading>Loading...</ng-template> <!--新的用这个-->

    2. if else 增强 

    <ng-template #loading>Loading...</ng-template> 
    <div *ngIf="user$ | async; else loading; let user">
      {{ user.name }}
    </div>

    我们可以很容易的写出这种等待 ajax 资料的代码. 

    let user 获取到的就是 user$.next 的 value 啦, loading 则是对应一个 ng-template.

    RC.5 更新 (一如往常, ng 在 RC 阶段依然可以加入新功能和 breaking change. 厉害吧)

    ngIf 和 ngFor 微语法新加入了 "as" 这个词法. 

    之前 *ngIf="user$ | async; else loading;let user"
    之后 *ngIf="user$ | async as user; else loading"

    取代了 let, 好处就是, 语义比较有连贯,比较熟悉.

    ngFor 也可以

    <!--之前-->
    <div *ngFor="let item of ['a','b','c'] as items; let i = index">
      {{item}} {{items.length}} {{i}}
    </div>
    
    <!--之后, 使用 as 替代了 let-->
    <div *ngFor="let item of ['a','b','c'] as items; index as i">
      {{item}} {{items.length}} {{i}}
    </div>
    
    <!--之后, 使用逗号","也可以哦 -->
    <div *ngFor="let item of ['a','b','c'] as items, index as i">
      {{item}} {{items.length}} {{i}}
    </div>

    3.  Replace references to TrackByFn to TrackByFunction<any> 

    4. Validators.email 

    this.form = this.fb.group({
      email : ["", Validators.email]
    });
    let emailCtrl = this.form.get("email");
    console.log(emailCtrl.valid); //fail
    emailCtrl.setValue("hengkeat87@gmail"); 
    console.log(emailCtrl.valid); //ok
    emailCtrl.setValue("hengkeat87@gmail.com"); 
    console.log(emailCtrl.valid); //ok

    这个没什么意义, 相信大家早就自己实现了. 应该是做给那些老师方便他们写 demo 教学生的吧...

    5. Validators.equalsTo

        this.form = this.fb.group({
           password : ["",Validators.equalsTo("confirmPassword")],
           confirmPassword : [""]
        });

    bug : https://github.com/angular/angular/issues/14770

    实现源码 : https://github.com/angular/angular/commit/7b7ae5f

    这个相信大家也自己实现了, 

    记得上次自己写的时候也是遇到 bug /. 

    6. Select option [compareWith]

     <form [formGroup]="form">
        <select [compareWith]="compareModel" formControlName="data" >
          <option *ngFor="let item of items; trackBy:trackBy" [ngValue]="item" >{{ item.text }}</option>
        </select>
     </form>
    type Item = { Id: number, value: string, text: string };
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html'
    })
    export class AppComponent {
      constructor(
        private fb: FormBuilder
      ) { }
      form: FormGroup
      items: Item[]
      trackBy: TrackByFunction<Item> = (index, item) => {
        return item.Id;
      }
      compareModel(a: Item, b: Item) {
        return a.Id === b.Id;
      }
      ngOnInit() {
        this.form = this.fb.group({
          data: [null]
        });
        this.items = [
          { Id: 1, value: "a", text: "A" },
          { Id: 2, value: "b", text: "B" },
          { Id: 3, value: "c", text: "C" }
        ];
        //this.form.get("data").setValue(this.items[0]); // 在没有 compareWith 的情况下,我们必须放回相同 reference 的对象 
        this.form.get("data").setValue({ Id: 1, value: "a", text: "A" }); //在设置 compareWith 后,我们可以给不同 reference 的对象
      }
    }

    关键就看最后两行的注释. 

    7. router runGuardsAndResolvers

        imports: [RouterModule.forRoot([
            { 
                path: 'home',
                component: HomeComponent
            },
            {
                path : "about",
                component : AboutComponent,
                runGuardsAndResolvers : "always", //"always" || "paramsChange" || "paramsOrQueryParamsChange" 选择不同的检测时机
                canActivate : [GuardService]
            },
            {
                path : "",
                redirectTo : "home",
                pathMatch : "full"
            }
        ])],

    通过 runGuardsAndResolvers 我们可以设置更多的守卫检查时机 (2.x版本只有在进入 route 的时候检查, 如果之后只是修改 params or queryParams 守卫是不会再检测的),  paramsChange 指的是 matrix. 

    8. RouteConfigLoadStart | RouteConfigLoadEnd

    route 多了2个 event 

    当一个 module 被加载 ( preload 也可以) 时就会触发. 主要用途是让我们知道 preload module 加载开始和完成了, 2.x 我们没法监听到. 

    9. Renderer 换成 Renderer2 了. 

    invokeElementMethod 没有了, 要怎样 focus 呢 ? 
    listenGlobal 没有了,  改用 listen("window" | "document" | "body"); 
     

    10.

    OpaqueToken 没有了, 改成 InjectionToken<T> 

    Injector.get 也有点更换, 支持类型了 

    let service = this.injector.get<T>(token: Type<T>|InjectionToken<T>, notFoundValue?: T): T; 

    以上的 T 必须是同一个类型哦. 虽然我放不同类型 typescript 也没有报错 /. 

    什么时候 formControl 才支持类型 . FormControl<T> 不是很好吗, formContril.value 就有类型可以用 ! 

    11. 

    ngOutletContext 改成 ngTemplateOutletContext

    也支持微语法了.

    <ng-template #myTemplate let-value="value" >
      <div>{{ value }}</div>
    </ng-template>
    <ng-template [ngTemplateOutlet]="myTemplate" [ngTemplateOutletContext]="{ value : 'keatkeat' }" ></ng-template>
    <div *ngTemplateOutlet="myTemplate; context : { value : 'keatkeat' }"></div> 

    12. call resolver when upstream params change

    2.x 版本的 router resolver 比较笨 

    from "/company/1/employer/1" change to "/company/2/employer/1" 

     

    children 的 resolve 是不会重跑一次的. 4.0 开始会跑,即使是 parent 的 route 改变了, child 的 resolve 也会重新跑一次. 这才对嘛 

    13. router CanDeactivate

    多了一个 parameter 

    @Injectable()
    export class BlockOut implements CanDeactivate<HomeComponent> {
        canDeactivate(
            component: HomeComponent,
            currentRoute: ActivatedRouteSnapshot,
            currentstate: RouterStateSnapshot,
            nextState?: RouterStateSnapshot
        ): Observable<boolean> | Promise<boolean> | boolean {
            console.log(currentstate.url); //  /home  
            console.log(nextState.url);    //  /about
            return true;
        }
    }

    我们依据 next url 来决定要干什么. 哎哟, 不错哦.

    14. SimpleChanges 多了一个 firstChange 熟悉, 早就该有了嘛!

    ngOnChanges(changes: SimpleChanges) {
        let c = changes["value"];
        if (c.firstChange) {
            console.log(c.previousValue); //undefined
            console.log(c.currentValue);  //keatkeat
            console.log(c.isFirstChange()); //true
        }
        else {       
            console.log(c.previousValue); //keatkeat
            console.log(c.currentValue);  //keatkeat2
            console.log(c.isFirstChange()); //false
        } 
    }

    15. MetaService 

    和 Title 类似, 就是让我们可以动态添加修改 Meta 等等. 我还没有测试 server side render , 4.0 好像也有一些变化. 希望有时间 ^^ 

    16. NgComponentOutlet

    refer : https://github.com/angular/angular/issues/11168

    这个功能是不错,不过我认为 ng 在动态 component 上面还有很多不足够的地方。 这个连 binding property, event 都没有,我不打算用, 没测试了.

    17 http params 容易写了

    this.http.get("http://localhost:61547/api/businesses",
      {
        params: { time: "2016-01-01T05:15:12.0000000+08:00" }
      }).subscribe(v => console.log(v));

    直接传入对象就可以了. (不过上面这个 time string convert 出来好像怪怪的... /.)

    18. Renderer2.setStyle

    之前是 setElementStyle, 

    setStyle(el: any, style: string, value: any, hasVendorPrefix: boolean, hasImportant: boolean)
    hasVendorPrefix 指的是这些 : 
     
    19. RequestOptionsArgs.search 换成 .params 
     
    20. Pipe 
    titlecase, uppercase, lowercase
    <h1>{{ title | titlecase }}</h1>

    titlecase 是说让第一个字母大写, "同时让后面的字母变小写", uppercase, lowercase 就不用介绍了吧. 

    21 ActivatedRoute.paramMap and queryParamMap

    其实 param 是可以有多个相同 key 的, 比如 ?data=10&data=11

    而获取的资料是 ActivatedRoute.params["data"] = ["10","11"]; 

    ng 为了要更好的区分这个情况而改进了,现在可以使用  ActivatedRoute.paramMap.get("data") or paramMap.getAll("data") 来做single and multiple 区分. 

     

     
     
  • 相关阅读:
    使用阿里云服务器的总结二-----目录权限
    使用阿里云服务器的总结一----修改配置
    thinkphp框架开启页面gzip压缩
    内容页分页代码
    js禁止中文输入 最简洁的【禁止输入中文】
    JS中setTimeout()的用法详解
    面向对象的5条基本设计原则
    C#_面试题1
    问题 E: C语言11.8
    问题 D: C语言11.7
  • 原文地址:https://www.cnblogs.com/keatkeat/p/6499046.html
Copyright © 2011-2022 走看看