关于angular1与angular2的应用区别

angular1.0的这些繁杂的api,还有它的执行速度,运行效率,学习曲线,都被人吐槽,最近一直在用ng1,实在很想吐槽。javascript

最近写ng2的项目,写了一些ng2基础的应用(包括angular-cli,路由,表单验证,组件通讯,ajax,服务/指令,lazyload)demo,地址在->点我css

学了一下angular2,看它有什么区别呢?html

我就不复述网上一堆的对比言论了,我仅仅对我项目里用到的一个点来进行阐述。vue

有个需求就是一个radio对应一个input标签,好比有两对。java

我须要选中1的时候传输1的value,选中2的时候传2的vaule。当选中1,2的input必须置空,选中2的时候1能够有值。还须要拿到数据之后还能显示回这个页面。react

ng1作的时候要radio俩ngModel,input俩ngModel,你须要判断radio是否是被选中。input的ngModel就不用管了。(好的办法是用事件代理,这样在传输数据没问题,很简单,数据回显的时候就要根据数据推radio的选中状况了,不操做dom的状况下还须要加ngModel,不过也是没办法的事,否则改交互好了)git

重要的一点是你必须$watch radio对应ngModel,若是没被选中,那2框置空。。坑的是若是我有好几个表单,我须要循环表单$watch!!!!坑死了。性能超差。(由于可能在代码里修改radio对应的ngModel来手动完成radio的惟一性,否则也不须要watch,事件代理也同样坑,回显的时候也必须手动维护一个数组来模拟radio的原生特性,可是能够避免$watch,由于发送请求数据不须要radio的状态,因此正在强烈建议重构这个页面)es6

开始ng2-----------------------------------------------------------------github

ng2一个好的点就是ngModel的转变,它作的很棒的一点是单项绑定和双向绑定的选择,ngModel也是。()是数据到模板的绑定,[ngModel]是模板到数据的绑定。ajax

ng2有Attribute, Class, and Style 绑定,Event Binding。并且都是能够拼接字符串或者在binding里面写表达式,甚至是函数,好比:

  ckass(){
      return " abc dec"
  }

<input type="text"  #spy1 [ngClass]="'hahaha'+ckass()" />

想用的心已经蠢蠢欲动了。。

普通的双向绑定如ng1是这样写

<input type="text" [(ngModel)]="input" />

重要的是它能够拆开:

<input type="checkbox" [ngModel]="input" (ngModelChange)="handleChange()"/>
 {{ input }}

(ngModelChange)是啥,它里面能够随便写吗?

答案是不能。借用雪狼大叔的翻译:安利一下angular.live

ngModelChange并非<input>元素的事件。 它其实是一个来自ngModel指令的事件属性。 当Angular在表单中看到一个[(x)]的绑定目标时, 它会期待这个x指令有一个名为x的输入属性,和一个名为xChange的输出属性。

双向绑定的指令都会有一个xxChange的属性,它能够修改绑定。好比咱们给它加个条件,若是radio选中了,就能够绑定啦, 否则你就是空吧。

<button class="batton" (click)="handleClick($event)"> click me</button>
<input type="checkbox" [ngModel]="input" (ngModelChange)="handleChange()"/>
<input type="text" [(ngModel)]="input" [disabled]="!check" />
  {{ input }}
export class AppComponent {
  check = false;
  handleChange(){
    this.check = !this.check;
    if(!this.check) {
      this.input = "";
    }
  }
  handleClick(e: any) { 
     this.check = false;
  }
}

这里留一个button来解决程序修改radio状态的问题。能够看到,咱们的handleChange其实就作了一个手动绑定的工做。若是没选中给置空。

运行你会发现,点击click me,input的内容并木有置空,由于radio的修改不是模板到数据的过程,是数据到模板的过程。

不要紧,[ngModel]的单项绑定仍然能够本身控制,好比:

@Component({
    selector: 'my-app',
    template: `
  <button class="batton" (click)="handleClick($event)"> click me</button>

  <input type="checkbox" [ngModel]="handleCheck()" (ngModelChange)="handleChange()"/>
  <input type="text" [(ngModel)]="input" [disabled]="!check" />
  {{ input }}
  `,
    styles: [``]
})

又来了个handleCheck,这是ng1的ngModel不能搞定的。反正不支持处理函数。

那ng2咋写:

export class AppComponent {
  check = false;
  handleCheck(){
    if (!this.check) {
      this.input = "";
    }
  }
  handleChange(){
    this.check = !this.check;
    if(!this.check) {
      this.input = "";
    }
  }
  handleClick(e: any) { 
     this.check = false;
  }
}

咱们在数据到模板的绑定只须要判断是否选中就能够了,这样就避免了$watch。

还有一些表达方式的不同,主要是由于都换成ts了,一些相似es6的语法都开始发挥做用。

1.模块注入

 由于es6的语法,去掉了ng1的依赖注入,改成模块化的注入,import语法

import { Component } from '@angular/core';
export class AppModule { }

2.模块化

因为ng2的模块化,本来模块化不那么明显的ng1的语法要改变不少,模块都做类,新增了注解语法,

@Component({
  selector: 'hero',
  templateUrl: 'component.html'
})
export class HeroFormComponent {
   ...  
}

Component注解规定了这个模块的selector,和模板template,而后把这个类作控制器。

3.数据展现

基本相似ng1,双花括号的展现方式

import { Component } from '@angular/core';
@Component({
  selector: 'my-app',
  template: `
    <h1>{{title}}</h1>
    <h2>My favorite hero is: {{myHero}}</h2>
    `
})
export class AppComponent {
  title = 'Tour of Heroes';
  myHero = 'Windstorm';
}

只是模板选择器写在了注解里,控制器为此类。

而后这个类就能够作为一个模块使用,其实就是ng1的组件型指令

<my-app>loading...</my-app>

另外,template里的一些自带指令也是相似ng1,只是写法不一样,除了上面写的绑定意外,再说一个ngFor

template: `
    <h1>{{title}}</h1>
    <h2>My favorite hero is: {{myHero}}</h2>
    <p>Heroes:</p>
    <ul>
      <li *ngFor="let hero of heroes">
        {{ hero }}
      </li>
    </ul>
  `

就是相似ng-repeat的做用了。只是换了个语法,看文档就行了。

4.dom事件

为了使键盘事件比较方便,而后本身封装进了ng2,vue已作此工做

<input #box
      (keyup.enter)="update(box.value)"
      (blur)="update(box.value)">

其他的事件都是相似的,带有()括号的单向绑定。

5.服务

服务也有点差距,注入和声明有点不一样,此为声明

import { Injectable } from '@angular/core';

@Injectable()
export class HeroService {
... }

当 TypeScript 看到@Injectable()装饰器时,就会记下本服务的元数据。 若是 Angular 须要往这个服务中注入其它依赖,就会使用这些元数据。

使用服务首先引入服务

import { HeroService } from './hero.service';

而后须要在注解里注册一下

 providers: [HeroService]

而后在这个类中就可使用这个服务了

export class AppComponent implements OnInit {
  title = 'Tour of Heroes';
  heroes: Hero[];

  constructor(private heroService: HeroService) { }
  getHeroes(): void {
    this.heroService.getHeroes().then(heroes => this.heroes = heroes);
  }
  ngOnInit(): void {
    this.getHeroes();
  }
}

6,生命周期

ng2增长了不少生命周期,如上面的ngOnInit等等,都是ng1没有的,就不介绍了

7,http

跟ng1相似ng2也是封装了ajax到http,不一样的是如今的ng2能够用rxjs了。。rxjs好像贵族的东西,用的人不多,学习成本不低,可是好用。ng2的http不是封装的promise了,而是简化的rx的Observable,须要subscribe来执行他的请求。也能够引入rx的toPromise,而后then下去就能够了。有点强破推销的意思。

8.管道

其实就是ng1的filter。

import { Pipe, PipeTransform } from '@angular/core';
/*
 * Raise the value exponentially
 * Takes an exponent argument that defaults to 1.
 * Usage:
 *   value | exponentialStrength:exponent
 * Example:
 *   {{ 2 |  exponentialStrength:10}}
 *   formats to: 1024
*/
@Pipe({name: 'exponentialStrength'})
export class ExponentialStrengthPipe implements PipeTransform {
  transform(value: number, exponent: string): number {
    let exp = parseFloat(exponent);
    return Math.pow(value, isNaN(exp) ? 1 : exp);
  }
}

@Pipe装饰器告诉Angular:这是一个管道,管道类实现了PipeTransform接口的transform方法,该方法接受一个输入值和一些可选参数,并返回转换后的值。transform方法返回就处理后的值。

9.路由

路由配置没什么说的,跟着文档一步步来就行了,因为是import的引入,不存在ng1包含路由很大的状况,根据配置来就行了。这种框架的路由都是相似的。

10. 组件交互

ng1如今都忘记了,主要说一下ng2的组件交互。

父传子的交互方式是靠props来传递的,这点跟react同样了,子组件的状态是纯靠输入,这是material的分页组件,在子组件里须要用装饰器来取,@input。下面例子就有

<md-paginator #paginator
                            [length]="xxx"
                            [pageIndex]="0"
                            [pageSize]="10"
                            [pageSizeOptions]="[10]">
            </md-paginator>

 子传父组件是不建议的,但也有不少需求,好比打开一个子组件作modal,而后modal关闭的时候回传给父组件数据,对于react的方案一个是redux,另外一个包括ng1也在用的就是事件系统。都有各自的事件系统,

可是ng2的事件系统最为强大,由于它是rxjs。

这里给一个例子:subject就是rxjs的对象。关于rxjs的介绍另有博文:rxjs-流式编程

@Component({
  selector: 'wap',
  template: '<app-add-warp [subject]="subject" ></app-add-warp>'
})
export class addWarpComponent {
  
    subject = new Subject();
    constructor() {
      this.subject.subscribe({
        next: (v) => console.log(v)
      });
    };
}

 

@Component({
  selector: 'app-add',
  templateUrl: './add.component.html',
  styleUrls: ['./add.component.scss']
})
export class AddComponent implements OnInit {
    @Input('subject') cbSubject:Subject<any>;
     constructor() {
    }
    ngOnInit() {
          this.cbSubject.next(this.user);   
    }    
  }
}    

 

subscribe就是触发事件要执行的东西,next方法就是触发事件的点。

相关文章
相关标签/搜索