• []angularjs 2.0官方新手入门教程(3)



    http://alvinwei.blog.163.com/blog/static/214666110201616101635843/


    2016-02-07 01:13:24|  分类: AngularJS2.0 |  标签:前端  angular  angularjs2.0  javascript  入门教程   


    本来说春节放假回来再翻译后面的,结果今天抽空又翻译了一篇。

    注:本篇教程代码承接上一篇教程点我去看

    正文开始

    1、上回我们已经能够用一个输入框去修改class里hero的name并显示出来,这篇继续做一些更复杂的事情。首先让我们先把网页启动起来,打开命令行,进入到网页所在的目录angular2-tour-of-heroes下输入npm start,成功启动网页后,不要关闭命令行。

    2、这次我们希望显示很多个hero而不是仅仅只有一个,所以我们要创建一个数组,打开app.component.ts,在最下面,也就是class AppComponent的外面,定义一个HEROES数组,如下所示:

    var HEROES: Hero[] = [ { "id": 11, "name": "Mr. Nice" }, { "id": 12, "name": "Narco" }, { "id": 13, "name": "Bombasto" }, { "id": 14, "name": "Celeritas" }, { "id": 15, "name": "Magneta" }, { "id": 16, "name": "RubberMan" }, { "id": 17, "name": "Dynama" }, { "id": 18, "name": "Dr IQ" }, { "id": 19, "name": "Magma" }, { "id": 20, "name": "Tornado" } ];


    3、接下来在class AppComponent里使用刚才定义的数组,创建一个变量叫做heroes,如下所示:

    public heroes = HEROES;


    4、下面我们要将这个数组显示出来,将下面的代码粘贴到@Componenttemplate中的title下面

    <h2>My Heroes</h2> <ul class="heroes"> <li *ngFor="#hero of heroes"> <!-- each hero goes here --> </li> </ul>

    这里我们可以看到<li>标签里的ngFor就是用来显示heroes数组的,而里面的(*)星号(#)井号是必不可少的,这里给一下官方对*ngFor="#hero of heroes"的解释:

    The (*) prefix to ngFor indicates that the <li> element and its children constitute a master template.
    The ngFor directive iterates over the heroes array returned by the AppComponent.heroes property and stamps out instances of this template.
    The quoted text assigned to ngFor means “take each hero in the heroes array, store it in the local hero variable, and make it available to the corresponding template instance”.
    The # prefix before "hero" identifies the hero as a local template variable. We can reference this variable within the template to access a hero’s properties.

    大概连翻译带解释一下,(*)放在ngFor前面代表<li>标签里面的内容会构成一个模板,ngFor从class AppComponent里取出heroes数组,并遍历里面每个元素后用这个模板显示出来"#hero of heroes"的意思是从heroes里取出每个hero对象,把他们赋给每个模板中的(#)井号后面所写的本地变量里,在这里就是#hero,这样每个模板中都有一个hero,但其实他们对应的是从class AppComponent中的heroes数组里取出的不同的hero对象。(#)放到hero前面就是将hero作为接收hero对象的变量名,这样我们可以在这个模板里通过这个变量名获取对应对象的属性进行操作,比如显示他的id,就是{{hero.id}},那假如我们把#hero of heroes修改成#evil of heroes,那么在使用的时候我们就需要将{{hero.id}}改成{{evil.id}}。

    5、上面的话听着有点绕,其实很好理解,比如我们现在要显示每一个hero的id和name,只需要将刚才代码中的<li>标签里的内容修改成这个样子:

    <li *ngFor="#hero of heroes"> <span class="badge">{{hero.id}}</span> {{hero.name}} </li>

    等待页面自动刷新,我们就可以看到更新后的页面显示出所有的英雄id和name了。现在,我们可以用Chrome检查元素去看一下这个列表的Elements,虽然我们只写了一个<li>标签,但是因为ngFor的遍历,会有很多个<li>标签显示出来,并且每个<li>里面的<span>对应的是不同的hero。因为<li>及其子元素<span>作为一个模板,被每个遍历后的hero套用很多次并显示出来。

    6、刚才你也许发现<span>标签里有cssclass,但我们并没有写任何css,所以现在我们就做这个东西,复制下面的css代码到app.component.ts中的@Component

    styles:[` .selected { background-color: #CFD8DC !important; color: white; } .heroes { margin: 0 0 2em 0; list-style-type: none; padding: 0; 10em; } .heroes li { cursor: pointer; position: relative; left: 0; background-color: #EEE; margin: .5em; padding: .3em 0em; height: 1.6em; border-radius: 4px; } .heroes li.selected:hover { color: white; } .heroes li:hover { color: #607D8B; background-color: #EEE; left: .1em; } .heroes .text { position: relative; top: -3px; } .heroes .badge { display: inline-block; font-size: small; color: white; padding: 0.8em 0.7em 0em 0.7em; background-color: #607D8B; line-height: 1em; position: relative; left: -1px; top: -4px; height: 1.8em; margin-right: .8em; border-radius: 4px 0px 0px 4px; } `]

    你会发现我们又一次使用了(`)符号,以便将css多行显示。
    注意:我们在@Component里定义的这个css并不会在别的地方起效果,他只作用于这个AppComponent

    7、下面我们给<ul>标签也加上我们刚才写的css样式,最终如下所示:

    <h2>My Heroes</h2> <ul class="heroes"> <li *ngFor="#hero of heroes"> <span class="badge">{{hero.id}}</span> {{hero.name}} </li> </ul>

    等待页面自动刷新,我们就可以看到换上新样式的hero列表了。

    8、接下来我们想要跟这个列表的元素进行互动,所以我们要给每个元素加上一个click事件,如下所示

    <li *ngFor="#hero of heroes" (click)="onSelect(hero)"> <span class="badge">{{hero.id}}</span> {{hero.name}} </li>

    这里的(click)="onSelect(hero)"代表了当我们点击某一个<li>标签时,会调用一个onSelect的函数,并将被点击的<li>标签中存储的那个hero对象作为参数传进去,()小括号在这里代表一个one way(单向)的data binding(数据绑定),方向是将hero传给onSelect函数。

    9、我们目前还没有onSelect这个函数,这个函数的用途是把我们在页面上单击的<li>中的hero传给class AppComponent里的一个叫selectedHero的变量,这样我们就可以在这个类中使用这个selectedHero。所以我们首先要添加一个selectedHero变量。在class AppComponent里添加selectedHero变量,就像之前添加heroes一样

    public selectedHero: Hero;

    这个变量并不用初始化,因为最开始也没有hero被选择。

    10、接下来我们要写onSelect这个函数了,在class AppComponent里,只需要一行:

    onSelect(hero: Hero) { this.selectedHero = hero; }

    这样我们选择的那个hero对象就传给了selectedHero。

    11、接下来我们要做的是把selectedHeroidname显示出来,修改上一篇教程中template的html代码,如下所示:

    <h2>{{selectedHero.name}} details!</h2> <div><label>id: </label>{{selectedHero.id}}</div> <div> <label>name: </label> <input [(ngModel)]="selectedHero.name" placeholder="name"/> </div>

    这个代码有个问题,等页面自动刷新过后,我们发现什么都显示不出来。通过Chrome的console会发现报错说“EXCEPTION: TypeError: Cannot read property 'name' of undefined in [null]”,原因是我们没有给selectedHero赋初值,那么网页刚加载完以后selectedHero就是null,他的id和name属性自然也就是undefined

    12、要解决这个问题很简单,要么是给selectedHero赋初值,比如heroes的第一个元素。可如果不这么做呢?也很简单,我们需要用一个叫做ngIf的东西用来判断是不是要处理这块涉及到selectedHero的html代码,所以我们给刚才的代码的外层加一个<div>标签,并在<div>里加上ngIf判断一下selectedHero是否是null,如下所示:

    <div *ngIf="selectedHero"> <h2>{{selectedHero.name}} details!</h2> <div><label>id: </label>{{selectedHero.id}}</div> <div> <label>name: </label> <input [(ngModel)]="selectedHero.name" placeholder="name"/> </div> </div>

    这个最外层的<div>的效果就是,如果selectedHero是null,那么就移除<div>及其里面的内容,注意,是移除,而不是hide(隐藏)。和ngFor一样,(*)星号在这里必不可少。完成以后,等待一下页面刷新,我们就会看到效果,当没有点击任何hero的时候,这部分页面是不会显示出来的。

    13、下面我们想要让被选择的hero所在的<li>看上去和其他的有些区别,之前第5步中的css style里有.selected一项,所以我们只要修改一下<li>标签,让他被选中的时候套用那个css就可以了,所以我们只要给li标签里增加一行代码:

    [class.selected]="hero === selectedHero"

    这里套在class.selected外面的[]中括号代表这是一个one-way(单向)的data binding(数据绑定),方向是将data source,即hero === selectedHero的值(true or false)传回给页面,如果class.selected是true那么就应用style中.selected的样式(关于()小括号和[]中括号,即data binding方向的解释可以看我上一篇教程结尾部分)。接下来等待页面刷新一下就可以看到效果了。

    下一篇年后放假回来继续翻译。

    最后,放一下这篇教程里完整的app.component.ts中的代码,如果之前按着教程某些步骤总是达不到预期的效果,可以来参照一下是不是有什么地方写的有问题:

    import {Component} from 'angular2/core'; interface Hero { id: number; name: string; } @Component({ selector: 'my-app', template:` <h1>{{title}}</h1> <h2>My Heroes</h2> <ul class="heroes"> <li *ngFor="#hero of heroes" [class.selected]="hero === selectedHero" (click)="onSelect(hero)"> <span class="badge">{{hero.id}}</span> {{hero.name}} </li> </ul> <div *ngIf="selectedHero"> <h2>{{selectedHero.name}} details!</h2> <div><label>id: </label>{{selectedHero.id}}</div> <div> <label>name: </label> <input [(ngModel)]="selectedHero.name" placeholder="name"/> </div> </div> `, styles:[` .selected { background-color: #CFD8DC !important; color: white; } .heroes { margin: 0 0 2em 0; list-style-type: none; padding: 0; 10em; } .heroes li { cursor: pointer; position: relative; left: 0; background-color: #EEE; margin: .5em; padding: .3em 0em; height: 1.6em; border-radius: 4px; } .heroes li.selected:hover { color: white; } .heroes li:hover { color: #607D8B; background-color: #EEE; left: .1em; } .heroes .text { position: relative; top: -3px; } .heroes .badge { display: inline-block; font-size: small; color: white; padding: 0.8em 0.7em 0em 0.7em; background-color: #607D8B; line-height: 1em; position: relative; left: -1px; top: -4px; height: 1.8em; margin-right: .8em; border-radius: 4px 0px 0px 4px; } `] }) export class AppComponent { public title = 'Tour of Heroes'; public heroes = HEROES; public selectedHero: Hero; onSelect(hero: Hero) { this.selectedHero = hero; } } var HEROES: Hero[] = [ { "id": 11, "name": "Mr. Nice" }, { "id": 12, "name": "Narco" }, { "id": 13, "name": "Bombasto" }, { "id": 14, "name": "Celeritas" }, { "id": 15, "name": "Magneta" }, { "id": 16, "name": "RubberMan" }, { "id": 17, "name": "Dynama" }, { "id": 18, "name": "Dr IQ" }, { "id": 19, "name": "Magma" }, { "id": 20, "name": "Tornado" } ];



  • 相关阅读:
    Ubuntu打开终端的方法三种
    javascript 获取随机数
    HTML5中类jQuery选择器querySelector的使用
    PHP stream_context_create()作用和用法分析
    一些常用的api接口、
    怎么样学好C++
    指针访问与数组访问的效率分析
    架构师
    Java 之 StringTokenizer
    类型转换操作符static_cast、const_cast、dynamic_cast、reinterpret_cast
  • 原文地址:https://www.cnblogs.com/ztguang/p/12646813.html
Copyright © 2020-2023  润新知