欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

慕客网 慕课网 Angular 打造企业级协作平台 学习入门教程视频 有大用 有大大用

1-1 Angular打造企业平台导学

需要的基础知识

image.png

1-2 环境搭建

image.png

使用淘宝镜像  (cnpm 的 c 是 sync 的意思) (i 是intall 安装的意思)

https://npm.taobao.org/   

# npm i -g cnpm 


安装脚手架  angular/cli  @表示范围的意思

快速构建应用,而不用繁琐的进行配置

# cnpm i -g @angular/cli


$ ng --version


     _                      _                 ____ _     ___

    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|

   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |

  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |

 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|

                |___/



Angular CLI: 8.3.2

Node: 10.16.0

OS: win32 x64

Angular:

...


Package                      Version

------------------------------------------------------

@angular-devkit/architect    0.803.2

@angular-devkit/core         8.3.2

@angular-devkit/schematics   8.3.2

@schematics/angular          8.3.2

@schematics/update           0.803.2

rxjs                         6.4.0



Administrator@Carl MINGW64 ~


指定版本号的安装 

$   cnpm i -g @angular/cli@1.1.0


$ ng new  新建一个子项目

$ ng build 构建一个项目

$ ng test 进行测试

image.png

https://code.visualstudio.com/    下载

安装 vs code 

image.png



扩展

image.png


image.png

image.png


http://chrome-extension-downloader.com  同样是 chrome 的扩展商店吧 

image.png

我还是使用的chrome的商店image.png




image.png



几个常用命令

image.png 

Mock Rest API

构建服务端的API的数据


image.png

# 安装  json-server 

npm install -g json-server



cmd 命令行执行启动服务

json-server ./mock/data.json


https://www.getpostman.com   下载 postman


image.png

postman   是api测试工具

rest client 也是是api测试工具,通过纯文本来描述这种请求  rest.http


image.png

如果出现错误

npm uninstall -g @angular/cli

npm cache clean

npm install -g @angular/cli





2-1 项目工程结构介绍

image.png


(--skip-install ( 可以简写为 -si )会跳过npm依赖的安装,速度会很快)

ng new taskmgr --skip-install  --style=scss


打开 vs code  


在 vs code 的命令终端

# cnpm install 出错

还是使用

# npm install 吧


# ng g m core             ( g就是 generate 产生的意思, 就是module的意思) 这里安装(创建)核心模块

# ng g m shared             ( g就是 generate 产生的意思, 就是module的意思) 这里安装(创建)共享模块



2-2 UI整体布局

image.png

# ng g c core/header  --spec=false      (c 表示组件components  --spec=false表示不想使用测试)

# ng g c core/footer  --spec=false      (c 表示组件components  --spec=false表示不想使用测试)

# ng g c core/sidebar  --spec=false      (c 表示组件components  --spec=false表示不想使用测试)



//启动 ng 服务

# ng serve


image.png

2-3 Material介绍


https://material.io  

https://material.io/components/  

https://material.io/design/


material示例的著名的优秀站点

http://materialdesignblog.com/material-design-showcase/


image.png


安装  @angular/material


# npm i --save @angular/material@2.0.0-beta.7 


我使用的是 下面的安装方法

#npm i --save @angular/material


https://material.io/color    为什么我这边是404 而人家的可以打开?

https://material.io/resources/color/#!/?view.left=0&view.right=0  这个可以打开


image.png

image.png



2-4 MdIcon 组件

image.png



图标字体  在里面可以直接找图标

https://material.io/resources/icons/?style=baseline


阿里巴巴矢量图标库 

https://www.iconfont.cn/



2-5 Input 组件

image.png


创建一个login的模块

# ng g m login

在login下创建一个叫login的组件

# ng g c login/login  --spec=false      (c 表示组件components  --spec=false表示不想使用测试)


是不是要安装 @angular/animations   因为 material 的很多控件有动画

# npm install --save @angular/animations




2-6 Card 和 Button 组件

image.png

image.png


2-7 在侧滑菜单中使用 MdList


image.png

这里 安装javascript?

# npm install --save date-fns

这里是安装把javascript转为typescript?

# npm i --save-dev  @types/date-fns


2-8 Angular Material 主题


@import '~@angular/material/prebuilt-themes/deeppurple-amber.css';

可以自定义主题   theme.scss是自定义的文件

@import  'theme.scss'  


https://www.materialpalette.com


image.png



2-9 GridList 打造注册页面头像列表


image.png

# ng g c login/register  --spec-false




2-10 对话框的使用

image.png


# ng g m project


$ ng g c projetc/project-list



2-11 Autocomplete 的使用

image.png


2-12 任务列表之菜单

image.png

# ng g m task


# ng g c task/task-home  --spec=false


# ng g c task/task-list  --spec=false


# ng g c task/task-item  --spec=false


# ng g c task/task-header  --spec=false



2-13 任务列表之任务组件


image.png





2-14 任务列表之新任务对话框

image.png

image.png


#  ng g c task/new-task --spec=false




2-15 任务列表之移动内容对话框


image.png



# ng g c task/copy-task --spec=false


2-16 完成主框架(上)

# ng g c shared/confirm-dialog -it -is --spec=false          ( -it 表示 --inline templete 内联式的模板, -is 表示 --inline style  内联式的style)


2-17 完成主框架(下)


#  ng g c task/new-task-list --spec=false


#  npm install hammerjs --save            ( hammerjs 是为了处理移动端的)


为什么使用下面的就会报错,( 把--save放在前面就会报错 )

#  npm install --save hammerjs   

npm ERR! code EINVALIDTAGNAME

npm ERR! Invalid tag name "": Tags may not have any characters that encodeURIComponent encodes.


npm ERR! A complete log of this run can be found in:

npm ERR!     C:\Users\Administrator\AppData\Roaming\npm-cache\_logs\2019-09-20T06_47_44_724Z-debug.log



3-1 初识 Angular Animation


animation 动画

image.png


https://www.w3.org/TR/web-animations-1/


image.png 




image.png


# npm i --save @angular/animations        ( i 就是 install 安装的意思 )




3-2 缓动函数和关键帧


image.png


缓动函数两个网站

https://easings.net/

https://cubic-bezier.com/   ( https://cubic-bezier.com/#.07,.56,.86,.64 )


image.png

image.png



3-3 项目卡片和任务动画


3-4 路由动画及高阶动画函数

image.png

image.png

image.png


4-1 依赖性注入


4-2 ChangeDetection

image.png

image.png

4-3 打造支持拖拽的属性型指令

image.png

image.png


# ng g m directive


# ng g d directive/drag --spec=false     (这里 d 表示 directive 指令的意思 ,,,,)


# ng g d directive/drop --spec=false


# ng g s directive/drag-drop   ( 这里 s 表示 service 服务 )



4-4 结构型指令、模块和样式

image.png

image.png


entryComponents : 是预先编译初始化(比如对话框,不是在模板里面的,是预先编译留给别人调用的)

exports: 模块里面的组件希望给大家共用的,要exports出来,否则别人没法使用,默认情况下declarations 里面的组件只能是自己模块使用


forRoot() : 第三方库及自带的库,比如 route (不仅有forRoot() 还有forChild() )


# ng g m services

image.png


image.png


4-5 模板驱动型表单处理

image.png

image.png


image.png

#  ng g c task/quick-task --spec=false



4-6 响应式表单处理和自定义表单控件(上)

响应式表单  其实也叫模型驱动型表单

image.png


image.png



4-7 响应式表单处理和自定义表单控件(下)


#  ng g c shared/image-list-select --spec=false



5-1 RxJS帮你走进响应式编程的世界

image.png

rxjs 官网

http://reactivex.io/


网页编辑器 rxjs

http://jsbin.com/

http://jsbin.com/qawivar/edit?html,js,console,output        qawivar 好像是视频作者的


image.pngimage.png


<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

  <div><input type="nubmer" id="height"></div>


  

  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>

</body>

</html>




const height = document.getElementById('height');

const height$ = Rx.Observable.fromEvent(height,'keyup');

height$.subscribe(val => console.log(val.target.value));




image.pngimage.png


<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

  <div><input type="text" id="length"></div>

  <div><input type="text" id="width"></div>

  <div id="area"></div>

  

  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>

</body>

</html>




const length = document.getElementById('length');

const width = document.getElementById('width');

const area = document.getElementById('area');

const length$ = Rx.Observable.fromEvent(length,'keyup').pluck('target','value');

const width$ = Rx.Observable.fromEvent(width,'keyup').pluck('target','value');

const area$ = Rx.Observable.combineLatest(length$,width$,(l,w)=>{return l*w; });

area$.subscribe(val=> area.innerHTML = val);


image.png





combineLatest (取最新的值)  改成 zip (就是两个新值是成对出现,只出现一个新值的话,结果不变)

image.png

image.png


5-2 常见操作符(一)

image.png

image.png



https://rxmarbles.com/

image.png

image.png



image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

  <div><input type="text" id="length"></div>

  <div><input type="text" id="width"></div>

  <div id="area"></div>

  

  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>

</body>

</html>




const length = document.getElementById('length');

const width = document.getElementById('width');

const area = document.getElementById('area');

const length$ = Rx.Observable.fromEvent(length,'keyup').map(ev=>ev.target.value);

const width$ = Rx.Observable.fromEvent(width,'keyup').map(ev=>ev.target.value);

const area$ = Rx.Observable.combineLatest(length$,width$,(l,w)=>{return l*w; });

area$.subscribe(val=> area.innerHTML = val);



mapTo(1) 常量 1

mapTo(2) 常量 2



image.png


<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

  <div><input type="text" id="length"></div>

  <div><input type="text" id="width"></div>

  <div id="area"></div>

  

  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>

</body>

</html>




const length = document.getElementById('length');

const width = document.getElementById('width');

const area = document.getElementById('area');

const length$ = Rx.Observable.fromEvent(length,'keyup').mapTo(1);

// const length$ = Rx.Observable.fromEvent(length,'keyup').map(_=>1);

const width$ = Rx.Observable.fromEvent(width,'keyup').mapTo(2);

//const width$ = Rx.Observable.fromEvent(width,'keyup').map(_=>2);

const area$ = Rx.Observable.combineLatest(length$,width$,(l,w)=>{return l*w; });

area$.subscribe(val=> area.innerHTML = val);


image.png

image.png



image.png


image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

  

    <div><input type="text" id="length"></div>

  <div><input type="text" id="width"></div>

  <div id="area"></div>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



const length = document.getElementById('length');

const width = document.getElementById('width');

const area = document.getElementById('area');

const length$ = Rx.Observable.of({id:1,value:20});

const width$ = Rx.Observable.fromEvent(width,'keyup').mapTo(2);

const area$ = Rx.Observable.combineLatest(length$,width$,(l,w)=>{return l.value*w; });

area$.subscribe(val=> area.innerHTML = val);


image.png




image.png


#    json-server ./mock/data.json



http://localhost:3000

http://localhost:3000/quotes

http://localhost:3000/quotes/1


5-3 常见操作符(二)

image.png

image.png

image.png

image.png


image.png


image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



const interval$ = Rx.Observable.interval(100);

interval$.subscribe(val=> console.log(val))


image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



const interval$ = Rx.Observable.interval(100).take(3);

interval$.subscribe(

  val=> console.log(val),

  err=> console.log(err),

  ()=>console.log('I am complete')

)


image.png


image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>


const interval$ = 

      Rx.Observable.interval(100).take(3);

const timer$ = 

      Rx.Observable.timer(100);


timer$.subscribe( v => console.log(v));


// interval$.subscribe(

//   function(val) {

//     console.log(val)

//   },

//   function (err) {

//     console.log(err)

//   },

//   function () {

//     console.log('I am complete')

//   }

// )


image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



const interval$ = 

      Rx.Observable.interval(100).take(3);

const timer$ = 

      Rx.Observable.timer(100,100);


timer$.subscribe( v => console.log(v));


// interval$.subscribe(

//   function(val) {

//     console.log(val)

//   },

//   function (err) {

//     console.log(err)

//   },

//   function () {

//     console.log('I am complete')

//   }

// )



image.png


<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



const interval$ = 

      Rx.Observable.interval(100)

      .map(val => val*2)

      .do(v => console.log('val is '+ v))

      .take(3);



interval$.subscribe(

  (val) =>console.log(val),

  function (err) {

    console.log(err)

  },

  function () {

    console.log('I am complete')

  }

)



image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



let logLabel = '当前值是';


const interval$ = 

      Rx.Observable.interval(100)

      .map(val => val*2)

      .do(v => {

        console.log( logLabel + v);

        logLabel = '当前'

       })

      .take(3);



interval$.subscribe(

  (val) =>console.log(val),

  function (err) {

    console.log(err)

  },

  function () {

    console.log('I am complete')

  }

)



image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



let logLabel = '当前值是';


const interval$ = 

      Rx.Observable.interval(100)

      .filter(val => val % 2 === 0)

      .do(v => {

        console.log( logLabel + v);

        logLabel = '当前'

       })

      .take(3);



interval$.subscribe(

  (val) =>console.log(val),

  function (err) {

    console.log(err)

  },

  function () {

    console.log('I am complete')

  }

)



image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



let logLabel = '当前值是';


const interval$ = 

      Rx.Observable.interval(100)

      .filter(val => val % 2 === 0)      

      .first();

// .first()  就相当于 take(1)



interval$.subscribe(

  (val) =>console.log(val),

  function (err) {

    console.log(err)

  },

  function () {

    console.log('I am complete')

  }

)




image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



let logLabel = '当前值是';


const interval$ = 

      Rx.Observable.interval(100)

      .filter(val => val % 2 === 0)      

      .last();

//last() 时 就是 never ,因为它是一个无穷序列,就是人为制造了一个empty


interval$.subscribe(

  (val) =>console.log(val),

  function (err) {

    console.log(err)

  },

  function () {

    console.log('I am complete')

  }

)



image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



let logLabel = '当前值是';


const interval$ = 

      Rx.Observable.interval(100)

      .filter(val => val % 2 === 0)      

      .skip(2);



interval$.subscribe(

  (val) =>console.log(val),

  function (err) {

    console.log(err)

  },

  function () {

    console.log('I am complete')

  }

)



scan((x,y)=>{return x+y }     ,,,,,,,,,,,x 表示累加器的值,把x+y累加器的值赋给x;;y是每次发射的值


image.png

image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



let logLabel = '当前值是';


const interval$ = 

      Rx.Observable.interval(100)

      .filter(val => val % 2 === 0)      

      .scan((x,y)=>{ return x+y; })

      .take(4);



interval$.subscribe( 

  (val) =>console.log(val),

  function (err) {

    console.log(err)

  },

  function () {

    console.log('I am complete')

  }

)



reduce 是把序列当中所有的东西,做最后一个累加值,只出来最后一个值, 

(因为这里它是一个无限的序列,所以算不出来,又制造了一个 never)

而scan是每次做叠加时,都会发射出来一个item


image.png


<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



let logLabel = '当前值是';


const interval$ = 

      Rx.Observable.interval(100)

      .filter(val => val % 2 === 0)      

      .reduce((x,y)=>{ return x+y; })

      .take(4);



interval$.subscribe( 

  (val) =>console.log(val),

  function (err) {

    console.log(err)

  },

  function () {

    console.log('I am complete')

  }

)


与 scan运算是一样的,只算一个最终值,只发射最终值

image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



let logLabel = '当前值是';


const interval$ = 

      Rx.Observable.interval(100)

      .filter(val => val % 2 === 0) 

      .take(4)

      .reduce((x,y)=>{ return x+y; })

      ;



interval$.subscribe( 

  (val) =>console.log(val),

  function (err) {

    console.log(err)

  },

  function () {

    console.log('I am complete')

  }

)


reduce 第一个参数是匿名函数,第二个参数是 x的初始值,x的初始值默认为 0 吧 

image.png


<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



let logLabel = '当前值是';


const interval$ = 

      Rx.Observable.interval(100)

      .filter(val => val % 2 === 0) 

      .take(4)

      .reduce((x,y)=>{ return [...x,y];},[]);

      



interval$.subscribe( 

  (val) =>console.log(val),

  function (err) {

    console.log(err)

  },

  function () {

    console.log('I am complete')

  }

)




image.png


image.png


<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>




let logLabel = '当前值是';


const interval$ = 

      Rx.Observable.interval(100)

      .map(val =>{

        throw '出错了'

      })

      .take(4)

      .reduce((x,y)=>{ return [...x,y];},[]);

      



interval$.subscribe( 

  (val) =>console.log(val),

  function (err) {

    console.log("Error"+err);

  },

  function () {

    console.log('I am complete')

  }

)



image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



let logLabel = '当前值是';


const interval$ = 

      Rx.Observable.never();

      

      



interval$.subscribe( 

  (val) =>console.log(val),

  function (err) {

    console.log("Error"+err);

  },

  function () {

    console.log('I am complete')

  }

)



image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



let logLabel = '当前值是';


const interval$ = 

      Rx.Observable.throw('出差了');

      

      



interval$.subscribe( 

  (val) =>console.log(val),

  function (err) {

    console.log("Error"+err);

  },

  function () {

    console.log('I am complete')

  }

)



image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



let logLabel = '当前值是';


const interval$ = 

      Rx.Observable.empty();

      

      



interval$.subscribe( 

  (val) =>console.log(val),

  function (err) {

    console.log("Error"+err);

  },

  function () {

    console.log('I am complete')

  }

)




image.png

image.png

image.png


image.png




5-4 常见操作符(三)


image.png

image.png


image.png

image.png



image.png

<!DOCTYPE html>


<html>


<head>


  <meta charset="utf-8">


  <meta name="viewport" content="width=device-width">


  <title>JS Bin</title>


</head>


<body>


  <div><input type="nubmer" id="length"></div>


  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>


</html>



const length = document.getElementById('length');


const length$ = Rx.Observable.fromEvent(length,'keyup').pluck('target','value')

.debounceTime(300);


length$.subscribe(val=> console.log(val));




image.png


<!DOCTYPE html>


<html>


<head>


  <meta charset="utf-8">


  <meta name="viewport" content="width=device-width">


  <title>JS Bin</title>


</head>


<body>


  <div><input type="nubmer" id="length"></div>


  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>


</html>



const length = document.getElementById('length');


const length$ = Rx.Observable.fromEvent(length,'keyup')

.pluck('target','value')

.debounce(()=>Rx.Observable.interval(300));


length$.subscribe(val=> console.log(val));



image.png

<!DOCTYPE html>


<html>


<head>


  <meta charset="utf-8">


  <meta name="viewport" content="width=device-width">


  <title>JS Bin</title>


</head>


<body>


  <div><input type="nubmer" id="length"></div>


  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>


</html>



const length = document.getElementById('length');


const length$ = Rx.Observable.fromEvent(length,'keyup')

.pluck('target','value')

.distinct();//不跟流以前所有的重复


length$.subscribe(val=> console.log(val));



image.png


<!DOCTYPE html>


<html>


<head>


  <meta charset="utf-8">


  <meta name="viewport" content="width=device-width">


  <title>JS Bin</title>


</head>


<body>


  <div><input type="nubmer" id="length"></div>


  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>


</html>



const length = document.getElementById('length');


const length$ = Rx.Observable.fromEvent(length,'keyup')

.pluck('target','value')

.distinctUntilChanged();//不跟上一个重复


length$.subscribe(val=> console.log(val));



image.png

<!DOCTYPE html>


<html>


<head>


  <meta charset="utf-8">


  <meta name="viewport" content="width=device-width">


  <title>JS Bin</title>


</head>


<body>


  <div><input type="nubmer" id="length"></div>

  

  <div><input type="nubmer" id="width"></div>


  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>


</html>




const length = document.getElementById('length');

const width = document.getElementById('width');

const length$ = Rx.Observable.fromEvent(length,'keyup')

.pluck('target','value');

const width$ = Rx.Observable.fromEvent(width,'keyup')

.pluck('target','value');


const merged$ = Rx.Observable.merge(length$,width$);//按照时间顺序输出两个流


merged$.subscribe(val=> console.log(val));




image.png

<!DOCTYPE html>


<html>


<head>


  <meta charset="utf-8">


  <meta name="viewport" content="width=device-width">


  <title>JS Bin</title>


</head>


<body>


  <div><input type="nubmer" id="length"></div>

  

  <div><input type="nubmer" id="width"></div>


  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>


</html>



const length = document.getElementById('length');

const width = document.getElementById('width');

const length$ = Rx.Observable.fromEvent(length,'keyup')

.pluck('target','value');

const width$ = Rx.Observable.fromEvent(width,'keyup')

.pluck('target','value');


const merged$ = Rx.Observable.concat(length$,width$)// concat 是先输出第一个所有流,再输出第二个所有流


merged$.subscribe(val=> console.log(val));


image.png

<!DOCTYPE html>


<html>


<head>


  <meta charset="utf-8">


  <meta name="viewport" content="width=device-width">


  <title>JS Bin</title>


</head>


<body>


  <div><input type="nubmer" id="length"></div>

  

  <div><input type="nubmer" id="width"></div>


  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>


</html>



const length = document.getElementById('length');

const width = document.getElementById('width');

const length$ = Rx.Observable.fromEvent(length,'keyup')

.pluck('target','value');

const width$ = Rx.Observable.fromEvent(width,'keyup')

.pluck('target','value');

const first$ = Rx.Observable.from([1,2,3,4]); 

const merged$ = Rx.Observable.concat(first$,width$);// concat 是先输出第一个所有流,再输出第二个所有流


merged$.subscribe(val=> console.log(val));



image.png

<!DOCTYPE html>


<html>


<head>


  <meta charset="utf-8">


  <meta name="viewport" content="width=device-width">


  <title>JS Bin</title>


</head>


<body>


  <div><input type="nubmer" id="length"></div>

  

  <div><input type="nubmer" id="width"></div>


  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>


</html>


const length = document.getElementById('length');

const width = document.getElementById('width');

const length$ = Rx.Observable.fromEvent(length,'keyup')

.pluck('target','value');

const width$ = Rx.Observable.fromEvent(width,'keyup')

.pluck('target','value');

const first$ = Rx.Observable.from([1,2,3,4])

.startWith(0); //就是在前面添加一个值;通常用来赋初始值,并且让一开始流是没有值的?

const merged$ = Rx.Observable.concat(first$,width$);


merged$.subscribe(val=> console.log(val));



image.png


<!DOCTYPE html>


<html>


<head>



  <meta name="viewport" content="width=device-width">


  <title>JS Bin</title>


</head>


<body>


  <div><input type="nubmer" id="length"></div>

  

  <div><input type="nubmer" id="width"></div>


  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>


</html>



const length = document.getElementById('length');

const width = document.getElementById('width');

const length$ = Rx.Observable.fromEvent(length,'keyup')

.pluck('target','value');

const width$ = Rx.Observable.fromEvent(width,'keyup')

.pluck('target','value');


const merged$ = Rx.Observable

.combineLatest(length$,width$,(l,w)=>l*w);


merged$.subscribe(val=> console.log(val));



image.png

<!DOCTYPE html>


<html>


<head>



  <meta name="viewport" content="width=device-width">


  <title>JS Bin</title>


</head>


<body>


  <div><input type="nubmer" id="length"></div>

  

  <div><input type="nubmer" id="width"></div>


  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>


</html>



const length = document.getElementById('length');

const width = document.getElementById('width');

const length$ = Rx.Observable.fromEvent(length,'keyup')

.pluck('target','value');

const width$ = Rx.Observable.fromEvent(width,'keyup')

.pluck('target','value');


const merged$ = Rx.Observable

.zip(length$,width$,(l,w)=>l*w);  //一一相对的,第一流的第一值与第二个流的第一个值 相乘,第一流的第二值与第二个流的第二个值 相乘,以此类推, 最慢的流决定最终的速度


merged$.subscribe(val=> console.log(val));




image.png

<!DOCTYPE html>


<html>


<head>



  <meta name="viewport" content="width=device-width">


  <title>JS Bin</title>


</head>


<body>


  <div><input type="nubmer" id="length"></div>

  

  <div><input type="nubmer" id="width"></div>


  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>


</html>




const length = document.getElementById('length');

const width = document.getElementById('width');

const length$ = Rx.Observable.fromEvent(length,'keyup')

.pluck('target','value');

const width$ = Rx.Observable.fromEvent(width,'keyup')

.pluck('target','value');


const merged$ = length$

.withLatestFrom(width$);  //以第一个流length$为主流,监听主流的变化,组成一个数组


merged$.subscribe(val=> console.log(val));



5-5 实战复杂表单控件(上)


# ng g c shared/age-input --spec=false


5-6 实战复杂表单控件(中)


5-7 实战复杂表单控件(下)




6-1 高阶操作符

image.png
















image.png



<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

  <div><input type="text" id="length"></div>

  <div><input type="text" id="width"></div>

  <div id="area"></div>

  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>

</body>


</html>




const length = document.getElementById('length');

const width = document.getElementById('width');

const length$ = Rx.Observable

    .fromEvent(length,'keyup')

    .pluck('target','value')

    .map(_=>Rx.Observable.interval(100)); 


length$.subscribe(val=>{

  console.log(val);

})




image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

  <div><input type="text" id="length"></div>

  <div><input type="text" id="width"></div>

  <div id="area"></div>

  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>

</body>


</html>




const length = document.getElementById('length');

const width = document.getElementById('width');

const length$ = Rx.Observable

    .fromEvent(length,'keyup')

    .pluck('target','value')

    .map(_=>Rx.Observable.interval(100)); 


length$.subscribe(val=>{

  val.subscribe( v => console.log(v));  

})





image.png


image.png





<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

  <div><input type="text" id="length"></div>

  <div><input type="text" id="width"></div>

  <div id="area"></div>

  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>

</body>


</html>




const length = document.getElementById('length');

const width = document.getElementById('width');

const length$ = Rx.Observable

    .fromEvent(length,'keyup')

    .pluck('target','value')

    .flatMap(_=>Rx.Observable.interval(100));  //两个流交替进行


length$.subscribe(val=> console.log(val)); 




flatMap  就是 mergeMap 的别名



image.png


<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

  <div><input type="text" id="length"></div>

  <div><input type="text" id="width"></div>

  <div id="area"></div>

  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>

</body>


</html>



const length = document.getElementById('length');

const width = document.getElementById('width');

const length$ = Rx.Observable

    .fromEvent(length,'keyup')

    .pluck('target','value')

    .switchMap(_=>Rx.Observable.interval(1000)); //  switchMap 是当第二个流时,第一个流断掉了

 

length$.subscribe(val=> console.log(val));  






image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

  <div><input type="text" id="length"></div>

  <div><input type="text" id="width"></div>

  <div id="area"></div>

  <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>

</body>


</html>



const length = document.getElementById('length');

const width = document.getElementById('width');

const length$ = Rx.Observable

    .fromEvent(length,'keyup')

    .pluck('target','value')

    .mergeMap(_=>Rx.Observable.interval(1000)); // mergeMap 与 flatMap 一样,交替进行的流输出来

 

length$.subscribe(val=> console.log(val));  


https://rxjs-dev.firebaseapp.com/api/operators/mergeMap

http://reactivex.io/rxjs/class/es6/Subject.js~Subject.html      好像不是

image.png



https://rxjs-dev.firebaseapp.com/api/operators/switchMap

image.png



# json-server ./mock/data.json --watch            (--watch 观察的意思,就是 data.json改动的话,会发映到服务器里面)



image.png





image.png


image.png



image.png




6-2 实战服务逻辑(上)


6-3 实战服务逻辑(中)


# npm i --save lodash    (javascript 里面提供的类库,专门处理数据,对像的一些提供了很多扩展的方法)


# npm i --save-dev @types/lodash    (还要装它这个类型)



# json-server ./mock/data.json     



# json-server ./mock/data.json --watch    



6-4 实战服务逻辑(下)



6-5 实战自动建议表单控件


# ng g  c shared/chips-list --spec=false



6-6 Observable 的冷和热以及 Subject

image.png

冷: 看视频,你先看,我也看视频,我是从头开始看的,,,,

热: 看央视直播,你先看,我也看央视直播,咱们看到的内容是一模一样的



image.png

subject 既是观察者,又是被观察对象

.同时实现了 Obervable  和 Observe


ReplaySubject            保留最新的n个值

BehaviorSubject  是ReplaySubject的一种特殊形式    保留最新的一个值


image.png


https://jsbin.com/?html,js,output




image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



const  count$ =

      Rx.Observable.interval(1000);

const sub1 = count$.subscribe(

  val=>console.log(val));


setTimeout(function(){

  const sub2 = count$.subscribe(

    val=>console.log(val));

},2000); 



以前上冷Observable(从头开始)




image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>




const  count$ =

      Rx.Observable.interval(1000).share(); 

const sub1 = count$.subscribe(

  val=>console.log(val));  


setTimeout(function(){

  const sub2 = count$.subscribe(

    val=>console.log(val));

},2000); 


热的 Observable




image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>




const  counter$ =

    Rx.Observable.interval(1000).take(5);


const subject = new Rx.Subject();


const observer1 = {

   next: (val)=>console.log("l:"+val),

   error: (err)=>console.error("Error>> l:"+err),

   complete:() =>console.log('1 is complete')

}


const observer2 = {

   next: (val)=>console.log("2:"+val),

   error: (err)=>console.error("Error>> 2:"+err),

   complete:() =>console.log('2 is complete')

}



subject.subscribe(observer1);


setTimeout(function(){

   subject.subscribe(observer2);

},2000);


counter$.subscribe(subject);



image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



const  counter$ =

    Rx.Observable.interval(1000).take(5);


const subject = new Rx.Subject();


const observer1 = {

   next: (val)=>console.log("l:"+val),

   error: (err)=>console.error("Error>> l:"+err),

   complete:() =>console.log('1 is complete')

}


const observer2 = {

   next: (val)=>console.log("2:"+val),

   error: (err)=>console.error("Error>> 2:"+err),

   complete:() =>console.log('2 is complete')

}



subject.subscribe(observer1);

subject.next(10);

subject.next(11);

setTimeout(function(){

   subject.subscribe(observer2);

},2000);


counter$.subscribe(subject);


subject 是一个热流hot流,类似于是一个电视直播


image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



const  counter$ =

    Rx.Observable.interval(1000).take(5);


const subject = new Rx.ReplaySubject(2); //最后两个重播

subject.next(10);

subject.next(11);


const observer1 = {

   next: (val)=>console.log("l:"+val),

   error: (err)=>console.error("Error>> l:"+err),

   complete:() =>console.log('1 is complete')

}


const observer2 = {

   next: (val)=>console.log("2:"+val),

   error: (err)=>console.error("Error>> 2:"+err),

   complete:() =>console.log('2 is complete')

}



subject.subscribe(observer1);


setTimeout(function(){

   subject.subscribe(observer2);

},2000);


counter$.subscribe(subject);




image.png

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width">

  <title>JS Bin</title>

</head>

<body>

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>


</body>

</html>



const  counter$ =

    Rx.Observable.interval(1000).take(5);


const subject = new Rx.BehaviorSubject();  // BehaviorSubject 只记住最新的最后一个值

subject.next(10);

subject.next(11);


const observer1 = {

   next: (val)=>console.log("l:"+val),

   error: (err)=>console.error("Error>> l:"+err),

   complete:() =>console.log('1 is complete')

}


const observer2 = {

   next: (val)=>console.log("2:"+val),

   error: (err)=>console.error("Error>> 2:"+err),

   complete:() =>console.log('2 is complete')

}



subject.subscribe(observer1);


setTimeout(function(){

   subject.subscribe(observer2);

},2000);


counter$.subscribe(subject);



6-7 实战身份验证控件和地址选择控件(上)

# ng g c shared/identity-input --spec=false


# ng g c shared/area-list --spec=false


6-8 实战身份验证控件和地址选择控件(中)


6-9 实战身份验证控件和地址选择控件(下)


7-1 Redux 的概念和实战(一)

image.png



Action 信号,事件,  中从Store中发出吗?

Reducer 计数器,进行处理;它是一个纯函数

Store 结果存在 Store中,然后程序就从Store中取数据


Store 里面的State值是不可改变的,它每次都返回一个新的State


chrome 的开发者工具 Reduc DevTools

image.png


redux  的依赖 ngrx,是google的angular团队的几个员工写的框架,用来在angular当中实现redux

它是anguarl/core框架的一个补充,不是必须的,官方鼓励大家用ngrx


下面是慕客网用的版本image.png

下面是我用的方法

# npm i --save @ngrx/core @ngrx/store @ngrx/router-store @ngrx/effects @ngrx/store-devtools



# npm install --save ngrx-store-freeze



7-2 Redux 的概念和实战(二)


# json-server ./mock/data.json


# ng serve


# npm i --save reselect 


reselect 提供了 从缓存读取数据,提高性能;合并多个输入型函数(除了最后一个) createSelector


image.png



7-3 什么是 Effects


reducer 是对内部的影响和改变(会改变store),跟ui相关的

effects   是对外部的影响和改变(跟dom,跟http请求相关的等)


image.png


# npm install -g concurrently          ( concurrently  就是并行 同时的意思)


image.png

# npm start 


7-4 实战认证信息流


# npm install --save lodash


# npm install --save-dev  @types/lodash


7-5 实战项目信息流(上)


7-6 实战项目信息流(中)

# npm install --save lodash


# npm install --save-dev @types/lodash



7-7 实战项目信息流(下)


7-8 实战任务列表信息流


7-9 实战任务 Reducer


7-10 实战任务 Effects


7-11 实战任务使用 Reducer 和 Effects


8-1 Angular 测试框架介绍

image.png

image.png

image.png

image.png


image.png

image.png


# ng g class reducers/auth.reducer --spec=true                # 为什么我执行这个命令会报错

                                                                                             # 而人家执行这个命令没事

image.png


# ng  test


8-2 单元测试 Service 和 Effects 以及集成测试

# ng g s services/auth  --spec (我这边不行)


# ng  test



# ng g class effects/auth.effects --spec  (我这边不行)



# ng  e2e



9-1 第三方组件的集成和懒加载

#    npm install --save angular-calendar

#    ng g m my-calendar

#    ng g c my-calendar/calendar-home -is -it --spec=false







9-2 项目总结

image.png

image.png

image.png




image.png

vs code 调试 


image.png

安装 chrome的调试插件后 ,重启下 vs code

image.png

image.png



设置断点 

然后启动 json-server 和  ng serve

看断点处的变量


image.png



webstorm调试

image.png


image.png


image.png

image.pngimage.png


image.pngimage.pngimage.pngimage.png



chrome 调试 


image.png

image.png



image.png

image.png


image.png



image.png

image.png















image.png

image.png



image.png










普通分类: