本文目录

  • 一、项目起步
  • 二、编写路由组件
  • 三、编写页面组件
    • 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-forvuejs中的v-for。 它会为列表中的每项数据复写它的宿主元素。

这时候可以看到页面变成下面这个样子:

接下来我们要把写死在HTML上面的数据,抽到JS中:

现在先新建一个books.ts文件来定义一个Book类,并添加idurltitleauthor四个属性:

// 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属性绑定语法。这是一种单向数据绑定。从 IndexComponentitem 属性绑定到目标元素的 list 属性,并映射到了 BooksComponentlist 属性。

做到这里,我们已经将BooksComponent作为IndexComponent的子组件来引用了,在实际开发过程中,这样的父子组件关系,会用的非常多。

写到这里,看看我们项目,还是一样正常在运行,只是现在项目中组件分工更加明确了。

现在的效果图:

本部分内容到这结束

Author 王平安
E-mail pingan8787@qq.com
博 客 www.pingan8787.com
微 信 pingan8787
每日文章推荐 https://github.com/pingan8787/Leo_Reading/issues
JS小册 js.pingan8787.com
微信公众号 前端自习课

【CuteJavaScript】Angular6入门项目(2.构建项目页面和组件)的更多相关文章

  1. 【CuteJavaScript】Angular6入门项目(1.构建项目和创建路由)

    本文目录 一.项目起步 二.编写路由组件 三.编写页面组件 1.编写单一组件 2.模拟数据 3.编写主从组件 四.编写服务 1.为什么需要服务 2.编写服务 五.引入RxJS 1.关于RxJS 2.引 ...

  2. 【CuteJavaScript】Angular6入门项目(3.编写服务和引入RxJS)

    本文目录 一.项目起步 二.编写路由组件 三.编写页面组件 1.编写单一组件 2.模拟数据 3.编写主从组件 四.编写服务 1.为什么需要服务 2.编写服务 五.引入RxJS 1.关于RxJS 2.引 ...

  3. 【CuteJavaScript】Angular6入门项目(4.改造组件和添加HTTP服务)

    本文目录 一.项目起步 二.编写路由组件 三.编写页面组件 1.编写单一组件 2.模拟数据 3.编写主从组件 四.编写服务 1.为什么需要服务 2.编写服务 五.引入RxJS 1.关于RxJS 2.引 ...

  4. SpringBoot学习入门之Hello项目的构建、单元测试和热部署等(配图文,配置信息详解,附案例源码)

    前言: 本文章主要是个人在学习SpringBoot框架时做的一些准备,参考老师讲解进行完善对SpringBoot构建简单项目的学习汇集成本篇文章,作为自己对SpringBoot框架的总结与笔记. 你将 ...

  5. gulp + webpack 构建多页面前端项目

    修改增加了demo地址 gulp-webpack-demo 之前在使用gulp和webpack对项目进行构建的时候遇到了一些问题,最终算是搭建了一套比较完整的解决方案,接下来这篇文章以一个实际项目为例 ...

  6. 160921、React入门教程第一课--从零开始构建项目

    工欲善其事必先利其器,现在的node环境下,有太多好用的工具能够帮助我们更好的开发和维护管理项目. 我本人不建议什么功能都自己写,我比较喜欢代码复用.只要能找到npm包来实现的功能,坚决不自己敲代码. ...

  7. Vue2+VueRouter2+webpack 构建项目实战(三):配置路由,运行页面

    制作.vue模板文件 通过前面的两篇博文的学习,我们已经建立好了一个项目.问题是,我们还没有开始制作页面.下面,我们要来做页面了. 我们还是利用 http://cnodejs.org/api 这里公开 ...

  8. webpack构建多页面react项目(webpack+typescript+react)

    目录介绍 src:里面的每个文件夹就是一个页面,页面开发相关的组件.图片和样式文件就存放在对应的文件夹下. tpl:里面放置模板文件,当webpack打包时为html-webpack-plugin插件 ...

  9. webpack4 + vue多页面项目精细构建思路

    #构建思路 虽然当前前端项目多以单页面为主,但多页面也并非一无是处,在一些情况下也是有用武之地的,比如: 项目庞大,各个业务模块需要解耦 SEO更容易优化 没有复杂的状态管理问题 可以实现页面单独上线 ...

随机推荐

  1. systemd概念和运行机制

    systemd概念 核心概念:单元 依赖关系 systemd事务 启动目标和运行级别 单元 早期CentOS版本中的服务管理脚本在CentOS7中被服务但源文件替换.系统初始化需要启动后台服务,需要完 ...

  2. ansible on aws linux 2

    1. 安装epel yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm 2. 安 ...

  3. Python拼接字符串的七种方式

    忘了在哪看到一位编程大牛调侃,他说程序员每天就做两件事,其中之一就是处理字符串.相信不少同学会有同感. 几乎任何一种编程语言,都把字符串列为最基础和不可或缺的数据类型.而拼接字符串是必备的一种技能.今 ...

  4. 【Luogu 1993】差分约束系统问题——小K的农场

    Luogu P1993 前置知识:最短路径相关算法 如果一个系统由n个变量和m个约束条件组成,形成m个形如ai-aj≤k的不等式(i,j∈[1,n],k为常数),则称其为差分约束系统. 显然题目中给出 ...

  5. 掌握Python系统管理-调试和分析脚本2- cProfile和timeit

    调试和分析在Python开发中发挥着重要作用. 调试器可帮助程序员分析完整的代码. 调试器设置断点,而剖析器运行我们的代码,并给我们执行时间的详细信息. 分析器将识别程序中的瓶颈.我们将了解pdb P ...

  6. Java面向基础概述和三大特性

    Java 是面向对象的高级编程语言,类和对象是 Java 程序的构成核心.围绕着 Java 类和 Java 对象,有三大基本特性:封装是 Java 类的编写规范.继承是类与类之间联系的一种形式.而多态 ...

  7. [ASP.NET Core 3框架揭秘] 配置[2]:读取配置数据[下篇]

    [接上篇]提到“配置”二字,我想绝大部分.NET开发人员脑海中会立即浮现出两个特殊文件的身影,那就是我们再熟悉不过的app.config和web.config,多年以来我们已经习惯了将结构化的配置定义 ...

  8. flanneld 安装

    目录 flanneld 安装 下载分发flanneld二进制文件 分发二进制文件到所有集群的节点 创建Flannel证书和私钥 创建证书签名请求 生成证书和私钥 向etcd写入Pod网段信息 创建fl ...

  9. Vue实现mp3音乐播放及动态进度条

    今天碰到一个Vue点击mp3播放及进度条动态走动的小功能,记录一下: 首先是通过HTML5 audio标签引入音频: <template> <div class="x-fo ...

  10. VLAN实验3(Hybrid接口的应用)

    本实验基于<HCNA网络技术实验指南> 本实验使用eNSP软件 原理概述: Hybrid接口既可以连接普通终端的接入链路又可以连接交换机间的干道链路,它允 许多个VLAN的帧通过,并可以在 ...