Angular4学习笔记(二):绑定和分包

原创 2017年04月17日 12:06:21

代码已提交至Github


src目录下的app/app.component.ts文件是一个标准的angular4组件的结构。

这里写图片描述

上面@component()括号内template属性里用`(这个符号不是单引号,而是键盘1左边、tab键上面的那个符号)包裹的是View,下面export的class部分是Controller。

希望实现的效果长这个样子:
这里写图片描述

万里长征第一步,先从修改View开始。

修改temlate里的HTML文件,改成下面的样子:

<h1>Hello,World</h1>
<p>你好,gundam meister</p>
<span>海牛高达</span>
<div>
    <span>海牛高达</span>
    <span>NewType</span>
</div>

上面部分先充当项目简介。

中间的span假装是高达列表。

下面的div包裹的两个span假装是高达详情。

刷新页面,现在是这个样子的:
这里写图片描述

好吧我承认和效果图比起来是挫了一点,但是现在先专注于功能实现。

需要实现的功能是:点击高达列表,可以显示高达详情

正常的情况下,当然不会用常量去渲染页面。而如何沟通Controller和View就是Angular用Model干的事情:绑定

绑定:你有我有全都有。

在同一个组件(component)内,在class(Controller)里定义的变量名,可以直接在template(View)里使用。

@Component({
    selector: 'my-app',
    template: `
    <h1>Hello,World</h1>
    <p>你好,gundam meister</p>
    <span>{{name}}</span>
    <div>
        <span>{{name}}</span>
        <span>{{type}}</span>
    </div>
    `
})
export class AppComponent {
    name = '海牛高达';
    type = 'NewType';
}

刷新页面,依然可以显示:
这里写图片描述

当然,gundam其实是一个类,所以现在是model上场的时候了。

定义一个类 gundam:

class Gundam {
    name: string;
    type: string;
}

改写name和type,让他们成为属性值而不是string常量:

gundam: Gundam = {
    name: '海牛',
    type: 'NewType'
};

typescript 的语法有点奇怪,定义某个变量是某种类型的写法,是变量名在前变量类型在后。

改变temple里的引用:

<h1>Hello,World</h1>
<p>你好,gundam meister</p>
<span>{{gundam.name}}</span>
<div>
    <span>{{gundam.name}}</span>
    <span>{{gundam.type}}</span>
</div>

刷新页面:
这里写图片描述

继续review代码。

主页展示的是一个gundam列表而不是某一个gundam,所以用一个gundam数组去冒充数据。

const gundams: Gundam[] = [
    {name: '海牛高达', type: 'NewType'},
    {name: '巴巴托斯', type: '近战'},
    {name: '力天使', type: '射击'}
];

之前的angular提供了ng-repeat的标签来循环列表,不过现在4.0以上的时代变成了标签里一个特殊的修饰:*ngFor

修改class里的代码,定义一个变量gundams接受数组:

gundams = GUNDAMS;

修改template,用*ngFor循环解析数组,进行数据渲染:

<h1>Hello,World</h1>
<p>你好,gundam meister</p>
<div *ngFor="let gundam of gundams">
    <span>
        {{gundam.name}}
    </span>
</div>
<div>
    <span>{{gundam.name}}</span>
    <span>{{gundam.type}}</span>
</div>

刷新页面:
这里写图片描述

列表已经根据数据来变化了(当然数据流还是有待商榷),下面来修改使得详情能根据点击的列表项变化。

每一个html标签都有事件(click hover 等等),而angular也继续调用了这些事件,只是写法不太一样。

<div *ngFor="let gundam of gundams" (click)="onSelected(gundam)">

解释:点击触发class中的onSelected方法,同时把gundam作为参数传递进去。

因为View里用到的onSected函数来自controller,也就是class,所以需要补充:

selectedGundam: Gundam; // 定义一个selectedGudam作为接收详情的变量
onSelected (gundam: Gundam) : void{
    this.selectedGundam = gundam; // 通过参数赋值
}

修改template中的html显示:

<div>
    <span>{{selectedGundam.name}}</span>
    <span>{{selectedGundam.type}}</span>
</div>

此时刷新页面会报错,因为虽然通过点击div可以给selectedGudam赋值,但是当selectedGundam被初始化的时候是没有值的。

有两种解决办法:

第一就是给selected设定初始值并设定初始被选择的div。

另一种就是根据selected有没有被初始化,决定显示不显示详情的div。

因为angular提供了ngIf修饰,用第二种方法会比较省事一点。

<div *ngIf="selectedGundam">
    <span>{{selectedGundam.name}}</span>
    <span>{{selectedGundam.type}}</span>
</div>

刷新页面
这里写图片描述
点击巴巴托斯
这里写图片描述

总的来说,写到这里业务逻辑已经完成了一半,甚至更多。因为本身项目就是一个点击查看的单页面应用,并不太复杂。但是所有的代码都挤在一个类里,可读性和扩展性都会变的很差。
所以是时候开始下一步了。

分包的精髓:

import {
Component
} from '@angular/core';
class Gundam {
    name: string;
    type: string;
}
const GUNDAMS: Gundam[] = [
    {name: '海牛高达', type: 'NewType'},
    {name: '巴巴托斯', type: '近战'},
    {name: '力天使', type: '射击'}
];
@Component({
    selector: 'my-app',
    template: `
        <h1>Hello,World</h1>
        <p>你好,gundam meister</p>
        <div *ngFor="let gundam of gundams" (click)="onSelected(gundam)">
            <span>
            {{gundam.name}}
            </span>
        </div>
        <div *ngIf="selectedGundam">
            <span>{{selectedGundam.name}}</span>
            <span>{{selectedGundam.type}}</span>
        </div>
    `
})
export class AppComponent {
    gundam: Gundam = {
    name: '海牛',
    type: 'NewType'
    };
    gundams = GUNDAMS;
    selectedGundam: Gundam; // 定义一个selectedGudam作为展示详情的变量
    onSelected (gundam: Gundam): void {
    this.selectedGundam = gundam; // 通过参数赋值
    }
}

现在一个component挤了太多的东西,有数据、有常量、有template和class。如果项目很小的话(比如这个demo)还可以接受,但是一旦业务逻辑繁琐起来就是totally disaster

就算不介意坑别人,也别给隔了很久再去维护的自己找麻烦。

先把gundam这个class给摘出来,既然是model就好好呆在model的地方。

在src下新建model的包,新建一个gundam.ts的文件,把gundam class给ctrl+x过去。
这里写图片描述

在原本的地方导入:

import { Gundam } from '../../model/gundam';

再把数组常量给挪走,理论上数据是需要从服务端取,但是我不写服务端好多年,所以还是继续使用假数据。

在src新建包service,新建data.ts文件,导入gundam类以后导出数组:

import { Gundam } from './../model/gundam';
export const GUNDAMS: Gundam[] = [
    {name: '海牛高达', type: 'NewType'},
    {name: '巴巴托斯', type: '近战'},
    {name: '力天使', type: '射击'}
];

在原位置引入使用:

import { GUNDAMS } from './../../service/data';

ps:不要忘记在每个文件后空一行.虽然不空可以正常运行,但是会有错误提示.总的来说就是这么一个格式要求.

此时可以正常显示,而app.component.ts里已经整洁多了。

但是还不够,现在要把详情分离出去。让上帝的归上帝,凯撒的归凯撒。主页就处理主页数据,详情就处理详情数据。

换句话说,把首页分成两个页面:首页 + 详情。

需要用到的就是route

PS,有关绑定:
Angular的绑定很有意思,有双向的也有单向的,有在class里声明一个变量在template里使用的,也有在template里暴露一个class里的变量给外界赋值的。目前我见到的是如下三种写法(指在view里):
1){{变量名}},单项绑定,class中的值会显示到view里。
2)[变量名],单项绑定,一般后面还会跟个“=”,用来给class里的变量或者属性赋值。
3)*ngModel=[(变量名)],双向绑定。有关双向绑定其实我还是有点不理解,官方文档上也只是在表单处理时应用。大体上说双向绑定就是绑定值后在页面修改值可以影响class内的值,而class内的值改变后view的值也会改变。
比如可以双向绑定一个input,初始化的时候从服务端读取一个值放进去,同时这个值是可以修改的。修改完毕class里的值也变了,可以直接提交而不用多写拿value的步骤。

版权声明:本文为博主原创文章,未经博主允许不得转载。

angularJS2 变量声明 var let const

变量声明let和const是JavaScript里相对较新的变量声明方式。 像我们之前提到过的,let在很多方面与var是相似的,但是可以帮助大家避免在JavaScript里常见一些问题。 const...
  • xiejunna
  • xiejunna
  • 2016年12月12日 15:53
  • 6614

angular4 环境变量配置

好久没有来了,今天风和日丽,就来分享个小知识,不扯淡,直接进入主题: 需求:使用angular实现前后分离开发,必然遇到环境问题,比如: 在本地开发你需要请求的地址是:www.bendi.com ...
  • maoguiyou
  • maoguiyou
  • 2017年11月06日 10:34
  • 811

Angular4中的输出属性

Angular4中的输出属性当子组件需要向父组件传递信息时需要用到输出属性。 举个栗子:当我们从股票交易所获得股票的实时价格时,希望外部也可以得到这个信息。为了方便,这里的实时股票价格我们通过一个随...
  • HaiJing1995
  • HaiJing1995
  • 2017年05月11日 17:06
  • 1038

Angular4的双向数据绑定

最近在学angular4,因为angularjs中默认是双向数据绑定,但是如果在比较复杂的页面使用的话会引起性能问题,那是因为angularjs会在页面保存一个所有数据绑定的列表,每当数据发生变化时,...
  • lucaslow
  • lucaslow
  • 2017年11月20日 20:42
  • 876

Angular开发(三)-关于属性绑定与事件绑定

说明:由于本人正在angular2或者说是angular4,只是把本人学习过程个人理解写出来,如果有写的不对的地方希望各位指出来,或者给我留言,相互学习。本人QQ:332904234 一、新建一个项目...
  • kuangshp128
  • kuangshp128
  • 2017年05月02日 20:42
  • 5156

Angular2学习笔记.4、表单相关,双向数据绑定,HeroForm

开始本次我们将会学会如何用Angular创建表单、two-way data binding(双向数据绑定)、change tracking(检测变化)、validation(验证) 和 error h...
  • github_33116729
  • github_33116729
  • 2016年02月22日 00:25
  • 10972

双向数据绑定---AngularJS的基本原理学习

Angular JS (Angular.JS) 是一组用来开发Web页面的框架、模板以及数据绑定和丰富UI组件。它支持整个开发进程,提供web应用的架构,无需进行手工DOM操作。 AngularJS很...
  • z69183787
  • z69183787
  • 2016年09月07日 16:54
  • 1710

Angular4 绑定html内容 警告处理

绑定html内容如果用正常的方法去绑定的话,可能会出再这种警告 --------------------------------------- WARNING: sanitizing HTML s...
  • xiaotuni
  • xiaotuni
  • 2017年08月14日 23:15
  • 2549

AngularJS操作数组

angularJS的数组操作的方法 1.数组的创建 有以下三种方法 (1)  var arrayObj = new Array(); //创建一个数组 (2)  var arrayObj = ne...
  • qq_36341800
  • qq_36341800
  • 2017年07月26日 10:01
  • 4763

Angular4学习笔记(四):service

一个service引发的解耦
  • catwindboy
  • catwindboy
  • 2017年04月17日 14:01
  • 7811
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Angular4学习笔记(二):绑定和分包
举报原因:
原因补充:

(最多只允许输入30个字)