Angular4学习笔记之实现绑定和分包


Posted in Javascript onAugust 01, 2017

本文介绍了Angular4学习笔记之实现绑定和分包,分享给大家,希望对大家有帮助

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

Angular4学习笔记之实现绑定和分包

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

希望实现的效果长这个样子:

Angular4学习笔记之实现绑定和分包

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

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

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

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

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

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

刷新页面,现在是这个样子的:
Angular4学习笔记之实现绑定和分包

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

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

正常的情况下,当然不会用常量去渲染页面。而如何沟通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';
}

刷新页面,依然可以显示:

Angular4学习笔记之实现绑定和分包

当然,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>

刷新页面:

Angular4学习笔记之实现绑定和分包

继续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>

刷新页面:

Angular4学习笔记之实现绑定和分包

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

每一个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>

刷新页面

Angular4学习笔记之实现绑定和分包 

点击巴巴托斯

Angular4学习笔记之实现绑定和分包

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

分包的精髓:

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过去。

Angular4学习笔记之实现绑定和分包

在原本的地方导入:

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的步骤。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery 渐变下拉菜单
Dec 15 Javascript
JavaScript操作DOM元素的childNodes和children区别
Apr 01 Javascript
JS实现登录页面记住密码和enter键登录方法推荐
May 10 Javascript
AngularJS通过$location获取及改变当前页面的URL
Sep 23 Javascript
BOM之navigator对象和用户代理检测
Feb 10 Javascript
jQuery插件zTree实现清空选中第一个节点所有子节点的方法
Mar 08 Javascript
JavaScript代码执行的先后顺序问题
Oct 29 Javascript
JS实现简单的星期格式转换功能示例
Jul 23 Javascript
Layui数据表格之获取表格中所有的数据方法
Aug 20 Javascript
js控制随机数生成概率代码实例
Mar 21 Javascript
Javascript异步流程控制之串行执行详解
Sep 27 Javascript
vue 使用微信jssdk,调用微信相册上传图片功能
Nov 13 Javascript
详解js静态资源文件请求的处理
Aug 01 #Javascript
Angular4学习笔记之准备和环境搭建项目
Aug 01 #Javascript
jQuery上传插件webupload使用方法
Aug 01 #jQuery
js实现鼠标拖拽多选功能示例
Aug 01 #Javascript
使用Node.js实现RESTful API的示例
Aug 01 #Javascript
关于jquery form表单序列化的注意事项详解
Aug 01 #jQuery
js下拉菜单生成器dropMenu使用方法详解
Aug 01 #Javascript
You might like
杏林同学录(五)
2006/10/09 PHP
php批量更改数据库表前缀实现方法
2013/10/26 PHP
PHP判断网络文件是否存在的方法
2015/03/12 PHP
php获取图片信息的方法详解
2015/12/10 PHP
php中使用websocket详解
2016/09/23 PHP
PHP使用递归算法无限遍历数组示例
2017/01/13 PHP
jquery 经典动画菜单效果代码
2010/01/26 Javascript
js Function类型
2011/12/04 Javascript
Jquery实现列表(隔行换色,全选,鼠标滑过当前行)效果实例
2013/06/09 Javascript
jQuery使用cookie与json简单实现购物车功能
2016/04/15 Javascript
使用js获取伪元素的content实例
2017/10/24 Javascript
Javascript的console['']常用输入方法汇总
2018/04/26 Javascript
Vue实现简单的留言板
2020/10/23 Javascript
使用Typescript开发微信小程序的步骤详解
2021/01/12 Javascript
[59:48]LGD vs IG 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
[01:04:20]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第一场 11.29
2020/12/02 DOTA
利用Python实现网络测试的脚本分享
2017/05/26 Python
Python处理Excel文件实例代码
2017/06/20 Python
Python爬虫实例扒取2345天气预报
2018/03/04 Python
python 编码规范整理
2018/05/05 Python
解决tensorflow测试模型时NotFoundError错误的问题
2018/07/26 Python
Python Flask框架模板操作实例分析
2019/05/03 Python
Django框架教程之中间件MiddleWare浅析
2019/12/29 Python
python 对象真假值的实例(哪些视为False)
2020/12/11 Python
英国第一家领先的在线处方眼镜零售商:Glasses Direct
2018/02/23 全球购物
美国领先的医疗警报服务:Philips Lifeline
2018/03/12 全球购物
豪华床上用品、床单和浴室必需品:Peacock Alley
2019/09/04 全球购物
荷兰家电销售网站:Welhof
2020/12/08 全球购物
领导的自我鉴定
2013/12/28 职场文书
工业学校毕业生自荐书
2014/01/03 职场文书
保密工作责任书
2014/04/16 职场文书
冬季安全检查方案
2014/05/23 职场文书
食堂厨师岗位职责
2014/08/25 职场文书
退税申请报告怎么写
2015/05/18 职场文书
运动会宣传语
2015/07/13 职场文书
AJAX学习笔记
2021/05/18 Javascript