Angular和BootStrap的一个简单demo
根据Angular5高级编程这本书第二章搭建的demo
参考博客:https://blog.csdn.net/crper/article/details/64443239
代码地址:https://github.com/Harry-ZH-Wang/AngularDemo
1. 添加bootstrap包
首先ng new 项目名称创建一个Angular工程,步骤和正常创建步骤相同,然后导入BootStrap包
如果不清楚怎么构建可以看:https://www.jianshu.com/p/65e603da0828
在package.json文件中添加BootStrap CSS 的包 : "bootstrap": "4.0.0-alpha.4"
"dependencies": { "@angular/animations": "~7.2.0", "@angular/common": "~7.2.0", "@angular/compiler": "~7.2.0", "@angular/core": "~7.2.0", "@angular/forms": "~7.2.0", "@angular/platform-browser": "~7.2.0", "@angular/platform-browser-dynamic": "~7.2.0", "@angular/router": "~7.2.0", "core-js": "^2.5.4", "rxjs": "~6.3.3", "tslib": "^1.9.0", "zone.js": "~0.8.26", "bootstrap": "4.0.0-alpha.4" }
cmd cd 到建立的项目的目录下面,执行nmp install下载bootstrap的包。
2. 添加css样式
在angular.json文件中添加bootstrap的css样式,angularJsDemo为项目名
"styles": [ "src/styles.css", "../angularJsDemo/node_modules/bootstrap/dist/css/bootstrap.css" ]
测试下bootstrap导入是否成功,我们修改下src下面的index.html
AngularJsDemo
测试列表
Add
标题 描述 第一行 no 第二行 no 第三行 no
启动一下,bootStrap的样式生效
这里只是做了个静态页面的展示,只是为了测试,下面按照书中的代码示例,添加Angular的功能
3. HTML页面添加Angular功能
通过cli建立的demo,在app目录下其实已经生成了一套配置的文件代码,这里为了自己体验下逻辑,就自己仿照着配置下
首先body 内容去掉,添加Angular 入口 标签,这里demo-app标签不是html标签,是自己随便写的一个,后续作为单页面APP的入口
AngularJsDemo Angular 入口
这里直接用TypeScript,它是javaScript的一个超集,除了自己的语法,也支持原生态的javaScript语法。在src/app 目录下新建一个demo文件夹,存放我们自己的TS文件,这里在demo文件夹下新建helloTS.ts,这里可以直接写JavaScript,不过既然玩新东西,那肯定要用TypeScript。
helloTs.ts文件
// 在创建JavaScript模块时,export 语句用于从模块中导出函数、对象或原始值,以便其他程序可以通过 import 语句使用它们/** * 这里的类做原始数据来源 */export class HelloModel { user; items; /** * 在一个类中只能有一个名为 “constructor” 的特殊方法。 * 一个类中出现多次构造函数 (constructor)方法将会抛出一个 SyntaxError 错误。 * 在一个构造方法中可以使用super关键字来调用一个父类的构造方法。 * 如果没有显式指定构造方法,则会添加默认的 constructor 方法。 * 如果不指定一个构造函数(constructor)方法, 则使用一个默认的构造函数(constructor)。 */ constructor() { this.user = 'Admin'; this.items = [new HelloItem('第一行', false), new HelloItem('第二行', false), new HelloItem('第三行', false)]; }}/** * 数据对像类 */export class HelloItem { action; done; constructor(action, done) { this.action = action; this.done = done; }}
这一步是构造一个页面展示的数据,实际情况数据来源应该是服务器来的,这里的demo,就前端构造一个数据对像列表,非必须。
3.1 创建模板
在angular中,向用户展示数据是通过模板来实现的,{{}} 这表示数据绑定
helloComponent.html 文件
{{getName()}}的测试列表
3.2 创建组件
Angular组件负责为模块提供所需数据合逻辑
helloComponent.ts文件
import { Component } from '@angular/core';import { HelloModel} from './helloTs';/** * @Component 标记为一个装饰器(组件) * selector: 'demo-app' 指定一个CSS选择器,匹配该组件要应用的HTML元素,这里就是我们刚刚自定义的元素 * templateUrl: 'helloComponent.html' 模板的路径,这里写的相对路径 也可以写绝对路径 app/demo/helloComponent.html */@Component({ selector: 'app-demo', templateUrl: 'helloComponent.html'})/** * 实例化一个对象 */export class AppHelloComponent { model = new HelloModel(); getName() { return this.model.user; }}
3.3 定义装饰器
通过@NgModule定义的属性来提供配置信息
helloModules.ts文件
import { BrowserModule } from '@angular/platform-browser';// 每个模块的定义必须有这个才能生效,ng2的开发模式就是类似一个树,从根节点无限发散import { NgModule } from '@angular/core';// 表单模块,比如你要在组件内用到一些表单元素或者数据绑定,不然会报错import { FormsModule } from '@angular/forms';// 自己定义的组件import {AppHelloComponent} from './helloComponent';@NgModule({ declarations: [ // 指令和组件 AppHelloComponent ], imports: [ // 比如你要引用那些模块的功能就要引入 BrowserModule, FormsModule ], providers: [], // 服务 bootstrap: [AppHelloComponent] // 启动的模块,一个app一般只有一个启动模块!})export class AppModule { }
3.4 配置main.ts引到文件
main.ts文件
// 引入生产模式,控制关闭开发模式的,函数控制import { enableProdMode } from '@angular/core';// app启动模块,必须引入import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';// import { AppModule } from './app/app.module';// 根模块,程序启动根页面import { AppModule} from './app/demo/helloModules';// 环境配置文件,可以写入接口路径什么的。。dev,prod各一份import { environment } from './environments/environment';if (environment.production) { enableProdMode();}// platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.error(err));// bootstrapModule是PlatformRef的一个方法,这个方法中实现了Module的初始化、Component的初始化等,是Angular的启动函数,此方法是基于浏览器,如果是移动例如Ionic框架,引到方法不一样platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.error(err));
配置完成了,启动测试下
4. 继续完善demo
4.1继续完善demo,通过Angular内置的结构指令加载List
三个常用的内置结构型指令: NgIf、NgFor和NgSwitch
中文手册地址:https://angular.cn/guide/structural-directives
首先添加一个getItems()方法获得之前构造的List
helloComponent.ts 文件
import { Component } from '@angular/core';import { HelloModel} from './helloTs';/** * @Component 标记为一个装饰器(组件) * selector: 'demo-app' 指定一个CSS选择器,匹配该组件要应用的HTML元素,这里就是我们刚刚自定义的元素 * templateUrl: 'helloComponent.html' 模板的路径,这里写的相对路径 也可以写绝对路径 app/demo/helloComponent.html */@Component({ selector: 'app-demo', templateUrl: 'helloComponent.html'})/** * 实例化一个对象 */export class AppHelloComponent { model = new HelloModel(); getName() { return this.model.user; } getItems() { return this.model.items; }}
使用内置的结构指令*ngFor循环列表 * 号不能省略
helloComponent.html 文件
{{getName()}}的测试列表
No 标题 描述 {{i + 1}} {{item.action}} 已办 代办
到这来就完成了数据的单向绑定,也就是展示的步骤
4.2 创建数据双向绑定
这来使用ngModel 来实现双向绑定,ngModel有三种写法,ngModel、[ngModel]和[(ngModel)]
[ngModel]为单向绑定,操作不会改变原有的值,[(ngModel)]为双向绑定,会改变原有值
简单说就是当你想从html的 input 组件去改动.ts对应的变量,,反之更动.ts的变量html对应的值也会改变,这时候就要使用双向绑定的功能
helloComponent.html文件
{{getName()}}的测试列表
No 标题 描述 操作 {{i + 1}} {{item.action}} 已办 代办
勾选checkbox后可以发现代办变为了已办
4.3 lambda表达式
这来可以通过一些语法糖来做些数据过滤,例如通过lambda函数来做数据过滤,这个时候勾选了后的数据会消失
helloComponent.ts 文件
import { Component } from '@angular/core';import {HelloItem, HelloModel} from './helloTs';/** * @Component 标记为一个装饰器(组件) * selector: 'demo-app' 指定一个CSS选择器,匹配该组件要应用的HTML元素,这里就是我们刚刚自定义的元素 * templateUrl: 'helloComponent.html' 模板的路径,这里写的相对路径 也可以写绝对路径 app/demo/helloComponent.html */@Component({ selector: 'app-demo', templateUrl: 'helloComponent.html'})/** * 实例化一个对象 */export class AppHelloComponent { model = new HelloModel(); getName() { return this.model.user; } getItems() { // filter 从数组项中选择一个子集,=>为lambda表达式(参数1, 参数2, …, 参数N) => { 函数声明 },这段代码等同于 function(item){return !item.done} return this.model.items.filter(item => !item.done); }}
上面做了删除的事件,这里再做个添加的事件
helloComponent.ts 文件
{{getName()}}的测试列表
Add
No 标题 描述 操作 {{i + 1}} {{item.action}} 已办 代办
helloComponent.ts
import { Component } from '@angular/core';import {HelloItem, HelloModel} from './helloTs';/** * @Component 标记为一个装饰器(组件) * selector: 'demo-app' 指定一个CSS选择器,匹配该组件要应用的HTML元素,这里就是我们刚刚自定义的元素 * templateUrl: 'helloComponent.html' 模板的路径,这里写的相对路径 也可以写绝对路径 app/demo/helloComponent.html */@Component({ selector: 'app-demo', templateUrl: 'helloComponent.html'})/** * 实例化一个对象 */export class AppHelloComponent { model = new HelloModel(); getName() { return this.model.user; } getItems() { // filter 从数组项中选择一个子集,=>为lambda表达式(参数1, 参数2, …, 参数N) => { 函数声明 },这段代码等同于 function(item){return !item.done} return this.model.items.filter(item => !item.done); } addInfo(info) { if (info !== '') { this.model.items.push(new HelloItem(info, false)); } }}
这里就完成了一个简单的前端demo,做个备注