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 相关文章推荐
javaScript对象和属性的创建方法
Jan 15 Javascript
广告代码静态化js通用函数
May 09 Javascript
javascript打印html内容功能的方法示例
Nov 28 Javascript
Javascript中call的两种用法实例
Dec 13 Javascript
网页右侧悬浮滚动在线qq客服代码示例
Apr 28 Javascript
jQuery中hover方法和toggle方法使用指南
Feb 27 Javascript
JavaScript实现点击单选按钮改变输入框中文本域内容的方法
Aug 12 Javascript
JavaScript常用数组算法小结
Feb 13 Javascript
基于 Node.js 实现前后端分离
Apr 23 Javascript
用js实现博客打赏功能
Oct 24 Javascript
javascript入门之string对象【新手必看】
Nov 22 Javascript
Javascript call及apply应用场景及实例
Aug 26 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
239军机修复记
2021/03/02 无线电
用libtemplate实现静态网页生成
2006/10/09 PHP
《PHP编程最快明白》第二讲 数字、浮点、布尔型、字符串和数组
2010/11/01 PHP
获取URL文件名后缀
2013/10/24 PHP
php表单敏感字符过滤类
2014/12/08 PHP
PHP设计模式之注册树模式分析
2018/01/26 PHP
PHP正则验证字符串是否为数字的两种方法并附常用正则
2019/02/27 PHP
Laravel事件监听器用法实例分析
2019/03/12 PHP
TextArea 控件的最大长度问题(js json)
2009/12/16 Javascript
深入理解JavaScript定时机制
2010/10/29 Javascript
js修改地址栏URL参数解决url参数问题
2012/12/15 Javascript
js 字符串转换成数字的三种方法
2013/03/23 Javascript
基于JavaScript实现动态添加删除表格的行
2016/02/01 Javascript
JavaScript中的this使用详解
2016/07/27 Javascript
Bootstrap实现渐变顶部固定自适应导航栏
2020/08/27 Javascript
js的三种继承方式详解
2017/01/21 Javascript
BootStrap 页签切换失效的解决方法
2017/08/17 Javascript
表格展示利器 Bootstrap Table实例代码
2017/09/06 Javascript
详解vue填坑之解决部分浏览器不支持pushState方法
2018/07/12 Javascript
vue新vue-cli3环境配置和模拟json数据的实例
2018/09/19 Javascript
JavaScript 实现同时选取多个时间段的方法
2019/10/17 Javascript
vue组件开发之slider组件使用详解
2020/08/21 Javascript
vue 使用 sortable 实现 el-table 拖拽排序功能
2020/12/26 Vue.js
Python实现求一个集合所有子集的示例
2018/05/04 Python
用python求一个数组的和与平均值的实现方法
2019/06/29 Python
使用python写一个自动浏览文章的脚本实例
2019/12/05 Python
django使用JWT保存用户登录信息
2020/04/22 Python
浅析python 通⽤爬⾍和聚焦爬⾍
2020/09/28 Python
HTML5 visibilityState属性详细介绍和使用实例
2014/05/03 HTML / CSS
韩语专业本科生求职信
2013/10/01 职场文书
护理毕业生自荐信范文
2013/12/22 职场文书
知识就是力量演讲稿
2014/09/13 职场文书
幼儿园六一儿童节演讲稿
2015/03/19 职场文书
2015年志愿者服务工作总结
2015/04/20 职场文书
教师节领导致辞
2015/07/29 职场文书
Python max函数中key的用法及原理解析
2021/06/26 Python