【CuteJavaScript】Angular6入门项目(2.构建项目页面和组件)
本文目录
- 一、项目起步
- 二、编写路由组件
- 三、编写页面组件
- 1.编写单一组件
- 2.模拟数据
- 3.编写主从组件
- 四、编写服务
- 1.为什么需要服务
- 2.编写服务
- 五、引入RxJS
- 1.关于RxJS
- 2.引入RxJS
- 3.改造数据获取方式
- 六、改造组件
- 1.添加历史记录组件
- 2.添加和删除历史记录
- 七、HTTP改造
- 1.引入HTTP
- 2.通过HTTP请求数据
- 3.通过HTTP修改数据
- 4.通过HTTP增加数据
- 5.通过HTTP删除数据
- 6.通过HTTP查找数据
三、编写页面组件
接下来开始编写页面组件,这里我们挑重点来写,一些布局的样式,后面可以看源码。
1.编写单一组件
我们首先写一个书本信息的组件,代码如下:
<!-- index.component.html -->
<div class="content">
<div class="books_box">
<!-- 单个课本 -->
<div class="books_item" *ngFor="let item of [1,2,3,4,5,6,7,8,9,10]">
<img class="cover" src="https://img3.doubanio.com/view/subject/m/public/s29988481.jpg">
<div class="title"><a>像火焰像灰烬</a></div>
<div class="author">程姬</div>
</div>
</div>
</div>
知识点:
*ngFor
是一个 Angular 的复写器(repeater)指令,就像angular1中的ng-for
和vuejs中的v-for
。 它会为列表中的每项数据复写它的宿主元素。
这时候可以看到页面变成下面这个样子:
接下来我们要把写死在HTML上面的数据,抽到JS中:
现在先新建一个books.ts
文件来定义一个Book
类,并添加id
,url
,title
和author
四个属性:
// src/app/books.ts
export class Book {
id: number;
url: string;
title: string;
author: string;
}
然后回到index.component.ts
文件去引入它,并定义一个books
属性,使用导入进来的Book
类作为类型:
// index.component.ts
import { Book } from '../books';
export class IndexComponent implements OnInit {
books: Book = {
id: 1,
url: 'https://img3.doubanio.com/view/subject/m/public/s29988481.jpg',
title: '像火焰像灰烬',
author: '程姬',
}
}
然后再改造前面的组件文件index.component.html
:
<!-- index.component.html -->
<div class="books_item" *ngFor="let item of [1,2,3,4,5,6,7,8,9,10]">
<img class="cover" src="{{books.url}}" alt="{{books.id}}">
<div class="title">
<a>{{books.title}}</a>
</div>
<div class="author">{{books.author}}</div>
</div>
接着,我们再为每个课本添加一个点击事件,来实现点击封面图能查看大图的效果,现在index.component.ts
中定义一个getDetailImage
方法,并在index.component.html
中绑定该方法:
// index.component.ts
export class IndexComponent implements OnInit {
getDetailImage(books){
alert(`正在查看id为${books.id}的大图!`);
}
}
这边方法的具体实现,不写,不是本文重点。下面是增加点击事件的绑定:
<!-- index.component.html -->
<img class="cover" src="{{books.url}}" alt="{{books.id}}" (click)="getDetailImage(books)">
知识点:
(click)
是Angular用来绑定事件,它会让 Angular 监听这个<img>
元素的 click
事件。 当用户点击 <img>
时,Angular 就会执行表达式 getDetailImage(books)
。
再来,我们引入前面学到的路由链接指令来改造HTML:
<!-- index.component.html -->
<a routerLink="/detail/{{books.id}}">{{books.title}}</a>
这时候,我们在点击书本的标题,发现页面跳转到URL地址为http://localhost:4200/detail/1
的页面,这就说明,我们页面的路由跳转也成功了~
改造完成后,可以看到,页面显示的还是一样,接下来我们先这样放着,因为我们后面会进行数据模拟,和模拟服务器请求。
我们就这样写好第一个单一组件,并且数据是从JS中读取的。
2.模拟数据
这时候为了方便后面数据渲染,我们这里需要模拟一些本地数据,我们创建一个本地mock-books.ts
文件来存放模拟的数据:
// app/mock-books.ts
import { Books } from './books';
export const BookList: Books[] = [
{
id: 1,
url: 'https://img3.doubanio.com/view/subject/m/public/s29988481.jpg',
title: '像火焰像灰烬',
author: '程姬',
},
// 省略其他9条
]
然后在index.component.ts
中导入模拟的数据,并将原有的books
值修改成导入的模拟数据BookList
:
// index.component.ts
import { BookList } from '../mock-books';
books = BookList;
并将原本的*ngFor
中修改成这样,绑定真正的数据:
<!-- index.component.html -->
<div class="books_item" *ngFor="let item of books">
<img class="cover" src="{{item.url}}" alt="{{item.id}}">
<div class="title">
<a>{{item.title}}</a>
</div>
<div class="author">{{item.author}}</div>
</div>
3.编写主从组件
当我们写完一个单一组件后,我们会发现,如果我们把每个组件都写到同一个HTML文件中,这是很糟糕的事情,这样做有缺点:
- 代码复用性差;(导致每次相同功能要重新写)
- 代码难维护;(因为一个文件会非常长)
- 影响性能;(打开每个页面都要重复加载很多)
为了解决这个问题,我们这里就要开始使用真正的组件化思维,将通用常用组件抽离出来,通过参数传递来控制组件的不同业务形态。
这便是我们接下来要写的主从组件。
思考一下,我们这里现在能抽成组件作为公共代码的,就是这个单个书本的内容,因为每个书本的内容都一致,只是里面数据的差异,于是我们再新建一个组件:
ng g component books
并将前面index.component.html
中关于课本的代码剪切到books.component.html
中来,然后删除掉*ngFor
的内容,并将原本本地的变量books
替换成list
,这个变量我们等会会取到:
<!-- books.component.html -->
<div class="books_item">
<img class="cover" src="{{list.url}}" alt="{{list.id}}" (click)="getDetailImage(list)">
<div class="title">
<a routerLink="/detail/{{list.id}}">{{list.title}}</a>
</div>
<div class="author">{{list.author}}</div>
</div>
再将这个组件,引用到它的父组件中,这里是要引用到index.component.html
的组件中,并将前面的*ngFor
再次传入<app-books>
:
<div class="content">
<div class="books_box">
<app-books *ngFor="let item of books"></app-books>
</div>
</div>
接下来要做的就是获取到list
变量的值,显然这个值是要从外面组件传进来的,我们需要在books.component.ts
引入前面定义的 Books
类 和 @Input() 装饰器
,还要添加一个带有 @Input() 装饰器
的 list
属性,另外还要记得将getDetailImage
方法也剪切过来:
// books.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { Books } from '../books';
export class BooksComponent implements OnInit {
@Input() list: Books;
constructor() { }
ngOnInit() {}
getDetailImage(books){
alert(`正在查看id为${books.id}的大图!`);
}
}
@Input() 装饰器
介绍具体可以查看 手册
我们要获取的 list
属性必须是一个带有@Input()
装饰器的输入属性,因为外部的 IndexComponent
组件将会绑定到它。就像这样:
<app-books *ngFor="let list of books" [list]="item"></app-books>
知识点:
[list]="item"
是 Angular
的属性绑定语法。这是一种单向数据绑定。从 IndexComponent
的 item
属性绑定到目标元素的 list
属性,并映射到了 BooksComponent
的 list
属性。
做到这里,我们已经将BooksComponent
作为IndexComponent
的子组件来引用了,在实际开发过程中,这样的父子组件关系,会用的非常多。
写到这里,看看我们项目,还是一样正常在运行,只是现在项目中组件分工更加明确了。
现在的效果图:
本部分内容到这结束
Author | 王平安 |
---|---|
pingan8787@qq.com | |
博 客 | www.pingan8787.com |
微 信 | pingan8787 |
每日文章推荐 | https://github.com/pingan8787/Leo_Reading/issues |
JS小册 | js.pingan8787.com |
微信公众号 | 前端自习课 |
【CuteJavaScript】Angular6入门项目(2.构建项目页面和组件)的更多相关文章
- 【CuteJavaScript】Angular6入门项目(1.构建项目和创建路由)
本文目录 一.项目起步 二.编写路由组件 三.编写页面组件 1.编写单一组件 2.模拟数据 3.编写主从组件 四.编写服务 1.为什么需要服务 2.编写服务 五.引入RxJS 1.关于RxJS 2.引 ...
- 【CuteJavaScript】Angular6入门项目(3.编写服务和引入RxJS)
本文目录 一.项目起步 二.编写路由组件 三.编写页面组件 1.编写单一组件 2.模拟数据 3.编写主从组件 四.编写服务 1.为什么需要服务 2.编写服务 五.引入RxJS 1.关于RxJS 2.引 ...
- 【CuteJavaScript】Angular6入门项目(4.改造组件和添加HTTP服务)
本文目录 一.项目起步 二.编写路由组件 三.编写页面组件 1.编写单一组件 2.模拟数据 3.编写主从组件 四.编写服务 1.为什么需要服务 2.编写服务 五.引入RxJS 1.关于RxJS 2.引 ...
- SpringBoot学习入门之Hello项目的构建、单元测试和热部署等(配图文,配置信息详解,附案例源码)
前言: 本文章主要是个人在学习SpringBoot框架时做的一些准备,参考老师讲解进行完善对SpringBoot构建简单项目的学习汇集成本篇文章,作为自己对SpringBoot框架的总结与笔记. 你将 ...
- gulp + webpack 构建多页面前端项目
修改增加了demo地址 gulp-webpack-demo 之前在使用gulp和webpack对项目进行构建的时候遇到了一些问题,最终算是搭建了一套比较完整的解决方案,接下来这篇文章以一个实际项目为例 ...
- 160921、React入门教程第一课--从零开始构建项目
工欲善其事必先利其器,现在的node环境下,有太多好用的工具能够帮助我们更好的开发和维护管理项目. 我本人不建议什么功能都自己写,我比较喜欢代码复用.只要能找到npm包来实现的功能,坚决不自己敲代码. ...
- Vue2+VueRouter2+webpack 构建项目实战(三):配置路由,运行页面
制作.vue模板文件 通过前面的两篇博文的学习,我们已经建立好了一个项目.问题是,我们还没有开始制作页面.下面,我们要来做页面了. 我们还是利用 http://cnodejs.org/api 这里公开 ...
- webpack构建多页面react项目(webpack+typescript+react)
目录介绍 src:里面的每个文件夹就是一个页面,页面开发相关的组件.图片和样式文件就存放在对应的文件夹下. tpl:里面放置模板文件,当webpack打包时为html-webpack-plugin插件 ...
- webpack4 + vue多页面项目精细构建思路
#构建思路 虽然当前前端项目多以单页面为主,但多页面也并非一无是处,在一些情况下也是有用武之地的,比如: 项目庞大,各个业务模块需要解耦 SEO更容易优化 没有复杂的状态管理问题 可以实现页面单独上线 ...
随机推荐
- hadoop伪分布式
一.安装jdk 1.下载解压 2.配置环境变量 配置成功: 二.ssh免密码登录 https://www.cnblogs.com/suwy/p/9326087.html 三.hadoop伪分布式配置 ...
- nyoj 42-一笔画问题 (欧拉图 && 并查集)
42-一笔画问题 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:10 submit:25 题目描述: zyc从小就比较喜欢玩一些小游戏,其中就包括画 ...
- nyoj 86-找球号(一)二分法
86-找球号(一) 内存限制:64MB 时间限制:3000ms 特判: No 通过数:14 提交数:48 难度:3 题目描述: 在某一国度里流行着一种游戏.游戏规则为:在一堆球中,每个球上都有一个整数 ...
- 【SpringBoot | Redis】SpringBoot整合Redis
SpringBoot整合Redis 1. pom.xml中引入Redis相关包 请注意,这里我们排除了lettuce驱动,采用了jedis驱动 <!-- redis的依赖 --> < ...
- 力扣(LeetCode)移除元素 个人题解
给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成 ...
- 领扣(LeetCode)七进制数 个人题解
给定一个整数,将其转化为7进制,并以字符串形式输出. 示例 1: 输入: 100 输出: "202" 示例 2: 输入: -7 输出: "-10" 注意: 输入 ...
- 【阿里巴巴-高德-汽车事业部】【内推】Java技术专家、前端技术专家、C++技术专家(长期招聘)
简历接收邮箱:yx185737@alibaba-inc.com 邮件请备注来自CSDN 一.Java技术专家 职位描述 研究汽车智能化和在线服务前沿技术,从事在线数据服务和车联网服务的设计和研发 负责 ...
- Redux中间件Redux-thunk的配置
当做固定写法吧 截图里少一个括号,已代码为主 import {createStore,applyMiddleware,compose} from 'redux' import thunk from ' ...
- 为什么服务器突然回复RST——小心网络中的安全设备
RST产生原因 一般情况下导致TCP发送RST报文的原因有如下3种: 1. SYN数据段指定的目的端口处没有接收进程在等待. 2.TCP想放弃一个已经存在的连接. 3.TCP ...
- HTML标签-->HTML5新增
HTML的Form新增属性 <form method="post" name="myForm"> <p> 邮箱:<input ty ...