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 (用setTimeout而非setInterval)
Dec 28 Javascript
深入document.write()与HTML4.01的非成对标签的详解
May 08 Javascript
JS操作Cookies的小例子
Oct 15 Javascript
jquery cookie的用法总结
Nov 18 Javascript
js表单中选择框值的获取及表单的序列化
Dec 17 Javascript
json数据处理及数据绑定
Jan 25 Javascript
js实现百度搜索提示框
Feb 05 Javascript
微信小程序开发之IOS和Android兼容的问题
Sep 26 Javascript
基于jQuery解决ios10以上版本缩放问题
Nov 03 jQuery
详解vue+vuex+koa2开发环境搭建及示例开发
Jan 22 Javascript
JS简单数组排序操作示例【sort方法】
May 17 Javascript
javascript中的offsetWidth、clientWidth、innerWidth及相关属性方法
May 14 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字符串中特殊符号的过滤方法介绍
2014/02/18 PHP
解析PHP的Yii框架中cookie和session功能的相关操作
2016/03/17 PHP
php中namespace及use用法分析
2016/12/06 PHP
php实现PDO中捕获SQL语句错误的方法
2017/02/16 PHP
PHP封装的完整分页类示例
2018/08/21 PHP
javascript add event remove event
2008/04/07 Javascript
基于JavaScript 数据类型之Boolean类型分析介绍
2013/04/19 Javascript
JavaScript取得键盘按下方向键是哪个的方法
2015/08/04 Javascript
JavaScript:Array类型全面解析
2016/05/19 Javascript
使用DeviceOne实现微信小程序功能
2016/12/29 Javascript
Kindeditor单独调用单图上传增加预览功能的实例
2017/07/31 Javascript
基于javascript 显式转换与隐式转换(详解)
2017/12/15 Javascript
通过vue手动封装on、emit、off的代码详解
2019/05/29 Javascript
JavaScript中跨域问题的深入理解
2021/03/04 Javascript
python模拟enum枚举类型的方法小结
2015/04/30 Python
Windows下实现Python2和Python3两个版共存的方法
2015/06/12 Python
python递归删除指定目录及其所有内容的方法
2017/01/13 Python
mysql 之通过配置文件链接数据库
2017/08/12 Python
Python实现希尔排序算法的原理与用法实例分析
2017/11/23 Python
分分钟入门python语言
2018/03/20 Python
面向初学者的Python编辑器Mu
2018/10/08 Python
python random从集合中随机选择元素的方法
2019/01/23 Python
Mac在python3环境下安装virtualwrapper遇到的问题及解决方法
2019/07/09 Python
Python re 模块findall() 函数返回值展现方式解析
2019/08/09 Python
Python 忽略文件名编码的方法
2020/08/01 Python
澳大利亚的奢侈品牌:Oroton
2016/08/26 全球购物
Perry Ellis官网:美国男士品味服装
2016/12/09 全球购物
软件测试题目
2013/02/27 面试题
《月迹》教学反思
2014/02/19 职场文书
捐赠仪式主持词
2014/03/19 职场文书
初中生散播谣言检讨书
2014/11/17 职场文书
工作会议通知
2015/04/15 职场文书
2015年乡镇民政工作总结
2015/05/13 职场文书
地道战观后感2000字
2015/06/04 职场文书
python迷宫问题深度优先遍历实例
2021/06/20 Python