wszgrcy

wszgrcy 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 该用户太懒什么也没留下

个人动态

wszgrcy 发布了文章 · 10月9日

angular共享依赖解决方案

webpack-ng-dll-plugin

  • ng版本可用的dll插件,路子比较野

用途

  • 提高打包速度
  • 代码复用(微前端依赖共享)

使用

  • 首先根据个人熟悉程度选择@angular-devkit/build-webpack,@angular-builders/custom-webpack,ngx-build-plus
第一个是官方的,后两个是第三方的,但是确认你有练过之前,请不要选择官方的...
作者在测试的时候选择的是@angular-builders/custom-webpack
  • 先构建dll,建议使用空项目来创建dll,因为目前开发中并没考虑到一些复杂逻辑的实现及相关第三方包的依赖关系保存(full模式应该可以实现,理论)
  • 然后在构建时引用
引用就是webpack的正常引用插件就ok了

尝鲜

  • 下面的函数过滤了index.html,styles,polyfills,License的输出,并且禁用了runtimeChunk
  setNgDllPlugin(
    config,
    {
        //webpack 的out相关配置
      output: {
        filename: 'dll.js',
      },
      ngDllPluginOptions: {
          // dll的资源清单导出配置
        path: path.join(__dirname, 'dist', 'manifest.json'),
        name: 'TLIB',
        format: true,
        filter: {
            // 过滤模式,full全量,auto相对于项目,manual 手动指定过滤项(需要设置map)
          mode: 'auto',
        },
      },
    },
    options
  );

自定义

  • 相关配置需要参考(暂时没写文档,需要查看源码)
  config.plugins.push(new NgDllPlugin(option.ngDllPluginOptions));

引用

// 这里的context可以理解为代码(应用代码)相对于哪个文件夹解析(不是打包出来的dll.js,如果正确引用,你会发现把dll.js删掉,也不会影响打包),如果发现打包出来的东西没有使用这个,应该就是这个配置错了
  config.plugins.push(
    new webpack.DllReferencePlugin({
      context: path.resolve(__dirname),
      manifest: require('./dist/manifest.json'),
    })
  );

演示地址

可能解锁的技术

  • 分体式路由加载
正常情况下,哪怕是动态加载的路由,也是与项目一同打包,只不过是打包为两个文件
主体项目先打包,然后再单独开发懒加载路由模块
  • web-component的使用率上升
虽然ng已经实现了这个,但是由于每次一大包,就相当于打了一个单独项目,非常庞大,使用dll后则会缩小到一个可怕的程度,副作用接近0

目前(可能)存在的问题

  • 资源清单输出的是全量的引用,但是实际上,只有mode:'full'时,才等价
没修改之一主要是影响不大,加上调试需要
  • 如果生成dll的项目中有动态加载模块,可能有未知影响
dll在设计的时候根本没考虑过动态模块之类的东西,完全就是只打一个大包
尽量使用空项目生成dll
  • auto只代表当前生成项目可以达到完全引用,如果你修改了项目,那么必须重新构建项目(额.看起来比较废物的一个模式)
其实如果项目代码足够多(各种种类),修改代码是不影响的,但是比如有些引入第一次使用,或者html模板中使用了一些新的东西,都需要重新构建

待改进

  • 主动排除一部分永远无法使用的导出

为什么dll比直接打包大

  • 即使dll打包现在使用到了ng的aot,摇树等相关优化技术,但是仍然有个致命问题,就是导出名,默认打包时,所有名字都会被优化(混淆),而dll打包就必须暴露这个名字,当完全暴露时,就会出现体积增长
目前用空项目生成出的dll(包括rxjs,router,common,core),全量暴力是440k(也就是说当其他包使用时这些文件都会在dll中查找),选择性导出最小化启动在216k作用,最终估计应该平均在300k左右
  • 目前使用的技术,只能1.全量导出,2.选择可用导出,这其实就有一个副作用存在,全量导出时.不仅一些不使用的依赖被导出了,还有些内部引用的(比如ɵangular_packages_core_core_h)也被强制导出了,从而增加了包大小
后期,其实可以整理一个永不导出的列表,进行排除,从而减小体积
  • 传统打包是多个模块打包一个模块,中间很多依赖都是属于内部依赖,所以精简了很多代码,dll的这种打包属于多模块,因此每个模块都有出口,之间的引用也是用的模块之间的引用,所以即使最小化dll也会比打包的多40k左右
查看原文

赞 0 收藏 0 评论 0

wszgrcy 发布了文章 · 9月21日

monaco使用vscode相关语法高亮在浏览器上显示

说明

  • 为了让monaco使用vscode的主题

尝试实现(弯路)

主题的直接转换

  • 刚开始本以为是两者主题的格式不同,尝试转换后发现还是不能正常使用
  • 结果发现两者的token根本不同,也就是分割代码每一部分的命名不同

monarch转换textmate

  • 发现monaco使用的是自己设计的monarch来实现语法高亮,但是vscode使用的是textmate的格式
textmate是苹果的那种
  • 于是想到如果实现一种转换逻辑,将textmate->monarch,那么monaco就可以使用vscode的主题了(因为token一样了)
  • 当学完双方的逻辑后,研究了posix与pcre正则的转换,进行事件时,发现一个致命问题..monach无法实现后行断言((?<=})),这就导致了普通的转换根本无法实现.(复杂的...可能有生之年系列吧)

最终解决方案

  • 使用vscode-textmate代替原monarch
  • 其实这个在开始研究的时候就有了,但是网上说因为不能直接调用c,所以使用wasm的效率比桌面端低,所以并没有有限考虑(有点自大了...)
  • 最终性能这块,看到了vscode-textmatebenchmark,测试了一波.发现除了js的解析比桌面端慢两倍,其他的甚至比桌面端快...有点费解了(不知道自己有没有研究错,如果有说的不对请拍砖)

jQuery v2.0.3

TOKENIZING 250971 lines using grammar source.js

Oniguruma: 550 ms., Onigasm: 381 ms. (1.4x faster)

Bootstrap CSS v3.1.1

TOKENIZING 127005 lines using grammar source.css

Oniguruma: 217 ms., Onigasm: 91 ms. (2.4x faster)

vscode.d.ts

TOKENIZING 264938 lines using grammar source.ts

Oniguruma: 356 ms., Onigasm: 191 ms. (1.9x faster)

JSON

TOKENIZING 103784 lines using grammar source.ts

Oniguruma: 312 ms., Onigasm: 185 ms. (1.7x faster)

Bootstrap CSS v3.1.1 minified

TOKENIZING 99967 lines using grammar source.css

Oniguruma: 231 ms., Onigasm: 167 ms. (1.4x faster)

jQuery v2.0.3 minified

TOKENIZING 83618 lines using grammar source.js

Oniguruma: 254 ms., Onigasm: 480 ms. (1.9x slower)

Bootstrap with multi-byte minified

TOKENIZING 116201 lines using grammar source.css

Oniguruma: 248 ms., Onigasm: 196 ms. (1.3x faster)

实现原理

  • 这个方案是从monaco-tm中得来的,但是最终完善了主题使用,可以从vscode中无缝移植主题,完善了语言插件,可以从vscode无缝迁移tmLanguage的插件,并且支持语言点注入
  • grammar是用来解析语法的,会在调用这个语言的时候,加载对应的语法文件
具体需要实现monaco.languages.EncodedTokensProvider接口传给setTokensProvider做参数

setTokensProvider代替了setMonarchTokensProvider

  • configuration是用来配置一些折叠,括号,注释等东西...和原来的monaco一样
  • theme就是用来请求加载主题的
因为语法的解析变成了vscode-textmate,所以不能使用传统的方式来加载主题,需要从Registry中拿到ColorMap然后定义给主题
  • 最后通过监听使用语言时加载对应的语法解析文件

使用

  • ng下已经封装好了依赖包的使用,非ng框架也可以稍作修改使用
  • 包地址cyia-ngx-common
  • 引入模块CyiaMonacoTextmateModule,组件中通过依赖注入拿到CyiaMonacoTextmateService服务

 this.service.setMonaco(monaco);

 this.service.init().then(async () => {

 const themeList = await this.service.getThemeList();

 this.themeList = themeList;

 this.selectedTheme = themeList[1];

 const name = await this.service.defineTheme(this.selectedTheme);

 this.instance = monaco.editor.create(

 this.containerElement?.nativeElement,

 {

 theme: name,

 value: `let a=6;`,

 language: this.selectedLanguage,

 minimap: {

 enabled: false,

 },

 automaticLayout: true,

 }

 );

 });

 //切换主题

 async change(e) {

 const name = await this.service.defineTheme(e);

 monaco.editor.setTheme(name);

 }

相关地址

查看原文

赞 0 收藏 0 评论 0

wszgrcy 发布了文章 · 8月1日

ng动态懒加载组件解决方案

这是什么

  • 正常的使用,是先声明组件,然后在模板中引入组件,这就导致了一个问题,如果一个组件的使用次数非常少,那么这个模块仍然会把组件打包进去,使得模块增大
  • 本项目先将组件当做正常标签写入,然后使用两个装饰器,一个为结构化懒加载指令,一个为自定义表单控件指令用来协助加载

需要前置知识

适用版本

  • ng10(100%)
  • ng9(接近100%)
ng9和ng10没太大改动,所以ng9应该没什么问题
  • ng8(如果不可以需要依赖路由实现)
  • ng7以下(需要依赖路由实现)
与8的路由实现方式不同,但是总体是依赖路由实现的

效果

  • 接近正常的开发只不过需要多个指令支持
  • 只在使用时,会动态请求相关组件
  • input完全相同
  • output 会变成CustomEvent类型,值再detail属性中
  • 表单控件在逻辑上应该完全一样
包括模板驱动式及响应式

思路

  • 通过动态加载并创建的web-component元素,本质上与普通标签完全一样
  • 所以说他就是个元素,无法响应双向绑定,需要通过指令来代替
input,select等类型都是通过指令实现的双向绑定,这也是本次组件的实现思路
  • 通过指令的中转,在需要懒加载的组件中加入一个事件(componentIsLoaded),在初始化时发射事件,值为这个组件的实例(this),通过拿到实例,将自定义表达控件相关的实现方法手动设置逻辑

代码地址

直接使用

@NgModule({
  imports: [
    LazyLoadModule.forRoot([
      [
        'libwc',//lazyLoad结构型指令请求加载时传入的健名
        (injector, compiler) =>
          import('libwc').then((e) =>//准备加载哪个模块,这里是通过tsconfig指定的路径映射,也可以直接使用相对路径
            createWebComponent(//创建web-component组件,封装的便捷方法,module需要有属性entry赋值为需要创建的组件
              injector,
              compiler,
              e.LibwcModule,
              'custom-libwc'// 页面上要写标签名
            )
          ),
      ],
    ]),
  ],

  schemas: [CUSTOM_ELEMENTS_SCHEMA],//自定义元素
})
export class AppModule {}

<!-- 这里使用的是非显示指令实现的的,可查看lazy-form.directive.ts文件 -->
    <custom-libwc *lazyLoad="'libwc'" formControlName="lazy"></custom-libwc>
<!-- 和上面的等同,为显示指令,引入模块自带 -->
      <custom-libwc  *lazyLoad="'libwc'" lazyLoadFormControl formControlName="lazy"></custom-libwc>
查看原文

赞 0 收藏 0 评论 0

wszgrcy 回答了问题 · 2019-08-22

nginx 转发后端请求,最大返回值不能超过10k.

结论1:不是配置问题是win10问题,ubuntu正常
结论2:暂时不清楚是win10版本问题还是某个软件冲突,使用的是ltsc
结论3:nginx 对于超过10k的数据,被fiddler抓取返回[Fiddler] ReadResponse() failed: The server did not return a complete response for this request. Server returned 0 bytes.

关注 1 回答 1

wszgrcy 提出了问题 · 2019-08-21

nginx 转发后端请求,最大返回值不能超过10k.

最终答案

  • fdm有个计划任务,当把那个关掉后正常了,不知道为什么他会默认限制80端口一次10k的大小,但是问题确实出现在他身上
  • 这个破问题,浪费了5天...................

以下的全部归档,可以作为排查的思路

  • 问题明朗了,80端口好像被限制了,一次只能传低于10k大小,高于的就像被拦截一样.因为我直接把后端地址监听了80端口,也是不行,跟nginx,docker没半毛钱关系,
  • 现在就是求一个精通windows的大佬给给我解答了,到底是怎么回事80莫名其妙被限制

最新猜测

  • 应该是跟响应头相关的配置(或者是其他能改变传送方式的)
  • 因为一步一步从nest到原生Node,并且减少了请求头后,能请求的数据也变多,那么说明应该是响应头和响应体共用了一个大小,应该是能把这个大小调大从而接收数据的

推翻所有猜测(包括上面的和下面的)

  • 使用环境win10,本机nginx,本机静态文件,直接访问静态文件,也是快超过10k时,立马处于长时间请求状态,然后失败.所以问题不在转发,不在代理上,就是在于nginx 拿到数据后,为何超过10k的数据,就不返回了,是我的操作系统问题,还是少了什么配置?这个问题这么难吗

目前已经在docker上,本机(win10)上试过,版本1.17.3,1.14.2,1.10.3,均不正常,考虑到我是一个初学者,肯定不能有个这么大的bug,nginx没解决,所以应该是配置问题吧

情景还原

  • 直接从后端(nestjs直接来的demo)请求数据,多大的都ok,使用postman
  • 走nginx的转发,最大不超过10k,超过就会一直处于请求状态,然后过一会失败
这里的最大大小我测试是文本长度在9700左右,docker中是9697,本机是9729,
  • 当超过后,并没有nginx的报错,反而是一个成功的日志,和普通的成功一模一样

相关代码

nginx配置

worker_processes 1;

events {
    worker_connections 1024;
}
http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;
    upstream nodejs {
        server 127.0.0.1:3000;
        keepalive 64;
    }
    server {
        listen 80;
        server_name 0.0.0.0;
        root /;
        location ~ ^/(api) {
            proxy_pass http://nodejs;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
        }
    }
}

## access.log日志
  • 第一个长度是9729的,postman/chrome上都能看到数据
  • 第二个长度是9730的,postman/chrome就会一直请求,直至失败
127.0.0.1 - - [20/Aug/2019:23:26:01 +0800] "GET /api/carnews HTTP/1.1" 200 9729 "-" "PostmanRuntime/7.13.0"
127.0.0.1 - - [20/Aug/2019:23:26:12 +0800] "GET /api/carnews HTTP/1.1" 200 9730 "-" "PostmanRuntime/7.13.0"

后端代码

  • 为了防止环境对问题的干扰,已经从docker内nest->主机nest->原生代码,另外原生代码又进一步...支持了9796数据.我感觉不是原生代码支持多了,而是好像应该是返回的响应头变少了,从而能拿到数据变多了
var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    let str = ''
    for (let i = 0; i < 9796; i++) {
        str = `${str}0`
    }
    console.log(str.length)
    res.end(str);
}).listen(3000, '127.0.0.1');

debug日志

  • debug抓取9729(能成功返回),9730(日志成功,返回不了的数据),根据我自己的分析,貌似两个日志没啥不同.........
#9729
2019/08/21 08:18:46 [debug] 3540#7264: *1 http cl:-1 max:1048576
2019/08/21 08:18:46 [debug] 3540#7264: *1 rewrite phase: 3
2019/08/21 08:18:46 [debug] 3540#7264: *1 post rewrite phase: 4
2019/08/21 08:18:46 [debug] 3540#7264: *1 generic phase: 5
2019/08/21 08:18:46 [debug] 3540#7264: *1 generic phase: 6
2019/08/21 08:18:46 [debug] 3540#7264: *1 generic phase: 7
2019/08/21 08:18:46 [debug] 3540#7264: *1 access phase: 8
2019/08/21 08:18:46 [debug] 3540#7264: *1 access phase: 9
2019/08/21 08:18:46 [debug] 3540#7264: *1 access phase: 10
2019/08/21 08:18:46 [debug] 3540#7264: *1 post access phase: 11
2019/08/21 08:18:46 [debug] 3540#7264: *1 generic phase: 12
2019/08/21 08:18:46 [debug] 3540#7264: *1 generic phase: 13
2019/08/21 08:18:46 [debug] 3540#7264: *1 http init upstream, client timer: 0
2019/08/21 08:18:46 [debug] 3540#7264: *1 http script copy: "X-Real-IP"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http script var: "127.0.0.1"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http script copy: "X-Forwarded-For"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http script var: "127.0.0.1"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http script copy: "Host"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http script var: "127.0.0.1"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http script copy: "Connection"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http script copy: "close"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http script copy: ""
2019/08/21 08:18:46 [debug] 3540#7264: *1 http script copy: ""
2019/08/21 08:18:46 [debug] 3540#7264: *1 http proxy header: "User-Agent: PostmanRuntime/7.13.0"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http proxy header: "Accept: */*"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http proxy header: "Cache-Control: no-cache"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http proxy header: "Postman-Token: 9ebcc43f-4cd8-4b43-8d6c-94abc434a597"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http proxy header: "accept-encoding: gzip, deflate"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http proxy header:
"GET /api/carnews HTTP/1.0
X-Real-IP: 127.0.0.1
X-Forwarded-For: 127.0.0.1
Host: 127.0.0.1
Connection: close
User-Agent: PostmanRuntime/7.13.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 9ebcc43f-4cd8-4b43-8d6c-94abc434a597
accept-encoding: gzip, deflate

"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http cleanup add: 02CD8F44
2019/08/21 08:18:46 [debug] 3540#7264: *1 init keepalive peer
2019/08/21 08:18:46 [debug] 3540#7264: *1 get keepalive peer
2019/08/21 08:18:46 [debug] 3540#7264: *1 get rr peer, try: 1
2019/08/21 08:18:46 [debug] 3540#7264: *1 stream socket 600
2019/08/21 08:18:46 [debug] 3540#7264: *1 connect to 127.0.0.1:3000, fd:600 #2
2019/08/21 08:18:46 [debug] 3540#7264: *1 select add event fd:600 ev:0
2019/08/21 08:18:46 [debug] 3540#7264: *1 select add event fd:600 ev:1
2019/08/21 08:18:46 [debug] 3540#7264: *1 http upstream connect: -2
2019/08/21 08:18:46 [debug] 3540#7264: *1 malloc: 0297DE58:128
2019/08/21 08:18:46 [debug] 3540#7264: *1 event timer add: 600: 60000:2978690325
2019/08/21 08:18:46 [debug] 3540#7264: *1 http finalize request: -4, "/api/carnews?" a:1, c:2
2019/08/21 08:18:46 [debug] 3540#7264: *1 http request count:2 blk:0
2019/08/21 08:18:46 [debug] 3540#7264: *1 post event 02D25648
2019/08/21 08:18:46 [debug] 3540#7264: *1 delete posted event 02D25648
2019/08/21 08:18:46 [debug] 3540#7264: *1 http upstream request: "/api/carnews?"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http upstream send request handler
2019/08/21 08:18:46 [debug] 3540#7264: *1 http upstream send request
2019/08/21 08:18:46 [debug] 3540#7264: *1 http upstream send request body
2019/08/21 08:18:46 [debug] 3540#7264: *1 chain writer buf fl:1 s:273
2019/08/21 08:18:46 [debug] 3540#7264: *1 chain writer in: 02CD8F80
2019/08/21 08:18:46 [debug] 3540#7264: *1 WSASend: fd:600, s:273
2019/08/21 08:18:46 [debug] 3540#7264: *1 chain writer out: 00000000
2019/08/21 08:18:46 [debug] 3540#7264: *1 event timer del: 600: 2978690325
2019/08/21 08:18:46 [debug] 3540#7264: *1 select del event fd:600 ev:1
2019/08/21 08:18:46 [debug] 3540#7264: *1 event timer add: 600: 60000:2978690326
2019/08/21 08:18:46 [debug] 3540#7264: *1 post event 02D11640
2019/08/21 08:18:46 [debug] 3540#7264: *1 delete posted event 02D11640
2019/08/21 08:18:46 [debug] 3540#7264: *1 http upstream request: "/api/carnews?"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http upstream process header
2019/08/21 08:18:46 [debug] 3540#7264: *1 malloc: 03145020:5242880
2019/08/21 08:18:46 [debug] 3540#7264: *1 WSARecv: fd:600 rc:0 9933 of 5242880
2019/08/21 08:18:46 [debug] 3540#7264: *1 http proxy status 200 "200 OK"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http proxy header: "X-Powered-By: Express"
2019/08/21 08:18:46 [debug] 3540#7264: *1 malloc: 02CD90C0:4096
2019/08/21 08:18:46 [debug] 3540#7264: *1 http proxy header: "Content-Type: text/html; charset=utf-8"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http proxy header: "Content-Length: 9729"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http proxy header: "ETag: W/"2601-azUGLq7ozrCoIXLEEuxlB9L/iQA""
2019/08/21 08:18:46 [debug] 3540#7264: *1 http proxy header: "Date: Wed, 21 Aug 2019 00:18:46 GMT"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http proxy header: "Connection: close"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http proxy header done
2019/08/21 08:18:46 [debug] 3540#7264: *1 HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Wed, 21 Aug 2019 00:18:46 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 9729
Connection: keep-alive
X-Powered-By: Express
ETag: W/"2601-azUGLq7ozrCoIXLEEuxlB9L/iQA"

2019/08/21 08:18:46 [debug] 3540#7264: *1 write new buf t:1 f:0 02CD91CC, pos 02CD91CC, size: 231 file: 0, size: 0
2019/08/21 08:18:46 [debug] 3540#7264: *1 http write filter: l:0 f:0 s:231
2019/08/21 08:18:46 [debug] 3540#7264: *1 http cacheable: 0
2019/08/21 08:18:46 [debug] 3540#7264: *1 http proxy filter init s:200 h:0 c:0 l:9729
2019/08/21 08:18:46 [debug] 3540#7264: *1 http upstream process upstream
2019/08/21 08:18:46 [debug] 3540#7264: *1 pipe read upstream: 0
2019/08/21 08:18:46 [debug] 3540#7264: *1 pipe preread: 9729
2019/08/21 08:18:46 [debug] 3540#7264: *1 pipe buf free s:0 t:1 f:0 03145020, pos 031450EC, size: 9729 file: 0, size: 0
2019/08/21 08:18:46 [debug] 3540#7264: *1 pipe length: 9729
2019/08/21 08:18:46 [debug] 3540#7264: *1 input buf #0
2019/08/21 08:18:46 [debug] 3540#7264: *1 pipe write downstream: 1
2019/08/21 08:18:46 [debug] 3540#7264: *1 pipe write downstream flush in
2019/08/21 08:18:46 [debug] 3540#7264: *1 http output filter "/api/carnews?"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http copy filter: "/api/carnews?"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http postpone filter "/api/carnews?" 02CD90B0
2019/08/21 08:18:46 [debug] 3540#7264: *1 write old buf t:1 f:0 02CD91CC, pos 02CD91CC, size: 231 file: 0, size: 0
2019/08/21 08:18:46 [debug] 3540#7264: *1 write new buf t:1 f:0 03145020, pos 031450EC, size: 9729 file: 0, size: 0
2019/08/21 08:18:46 [debug] 3540#7264: *1 http write filter: l:0 f:0 s:9960
2019/08/21 08:18:46 [debug] 3540#7264: *1 http write filter limit 0
2019/08/21 08:18:46 [debug] 3540#7264: *1 WSASend: fd:596, s:9960
2019/08/21 08:18:46 [debug] 3540#7264: *1 http write filter 00000000
2019/08/21 08:18:46 [debug] 3540#7264: *1 http copy filter: 0 "/api/carnews?"
2019/08/21 08:18:46 [debug] 3540#7264: *1 pipe write downstream done
2019/08/21 08:18:46 [debug] 3540#7264: *1 event timer: 600, old: 2978690326, new: 2978690340
2019/08/21 08:18:46 [debug] 3540#7264: *1 http upstream exit: 00000000
2019/08/21 08:18:46 [debug] 3540#7264: *1 finalize http upstream request: 0
2019/08/21 08:18:46 [debug] 3540#7264: *1 finalize http proxy request
2019/08/21 08:18:46 [debug] 3540#7264: *1 free keepalive peer
2019/08/21 08:18:46 [debug] 3540#7264: *1 free rr peer 1 0
2019/08/21 08:18:46 [debug] 3540#7264: *1 close http upstream connection: 600
2019/08/21 08:18:46 [debug] 3540#7264: *1 free: 0297DE58, unused: 88
2019/08/21 08:18:46 [debug] 3540#7264: *1 event timer del: 600: 2978690326
2019/08/21 08:18:46 [debug] 3540#7264: *1 select del event fd:600 ev:0
2019/08/21 08:18:46 [debug] 3540#7264: *1 reusable connection: 0
2019/08/21 08:18:46 [debug] 3540#7264: *1 http upstream temp fd: -1
2019/08/21 08:18:46 [debug] 3540#7264: *1 http output filter "/api/carnews?"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http copy filter: "/api/carnews?"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http postpone filter "/api/carnews?" 02EBF6A0
2019/08/21 08:18:46 [debug] 3540#7264: *1 write new buf t:0 f:0 00000000, pos 00000000, size: 0 file: 0, size: 0
2019/08/21 08:18:46 [debug] 3540#7264: *1 http write filter: l:1 f:0 s:0
2019/08/21 08:18:46 [debug] 3540#7264: *1 http copy filter: 0 "/api/carnews?"
2019/08/21 08:18:46 [debug] 3540#7264: *1 http finalize request: 0, "/api/carnews?" a:1, c:1
2019/08/21 08:18:46 [debug] 3540#7264: *1 set http keepalive handler
2019/08/21 08:18:46 [debug] 3540#7264: *1 http close request
2019/08/21 08:18:46 [debug] 3540#7264: *1 http log handler
2019/08/21 08:18:46 [debug] 3540#7264: *1 free: 03145020
2019/08/21 08:18:46 [debug] 3540#7264: *1 free: 02CD80B8, unused: 0
2019/08/21 08:18:46 [debug] 3540#7264: *1 free: 02CD90C0, unused: 3151
2019/08/21 08:18:46 [debug] 3540#7264: *1 free: 02CE10D0
2019/08/21 08:18:46 [debug] 3540#7264: *1 hc free: 00000000
2019/08/21 08:18:46 [debug] 3540#7264: *1 hc busy: 00000000 0
2019/08/21 08:18:46 [debug] 3540#7264: *1 tcp_nodelay
2019/08/21 08:18:46 [debug] 3540#7264: *1 reusable connection: 1
2019/08/21 08:18:46 [debug] 3540#7264: *1 event timer add: 596: 65000:2978695340
2019/08/21 08:19:51 [debug] 3540#7264: *1 event timer del: 596: 2978695340
2019/08/21 08:19:51 [debug] 3540#7264: *1 http keepalive handler
2019/08/21 08:19:51 [debug] 3540#7264: *1 close http connection: 596
2019/08/21 08:19:51 [debug] 3540#7264: *1 select del event fd:596 ev:0
2019/08/21 08:19:51 [debug] 3540#7264: *1 reusable connection: 0
2019/08/21 08:19:51 [debug] 3540#7264: *1 free: 00000000
2019/08/21 08:19:51 [debug] 3540#7264: *1 free: 0297DD50, unused: 28
#9730
2019/08/21 08:11:08 [debug] 15264#18204: *1 http cl:-1 max:1048576
2019/08/21 08:11:08 [debug] 15264#18204: *1 rewrite phase: 3
2019/08/21 08:11:08 [debug] 15264#18204: *1 post rewrite phase: 4
2019/08/21 08:11:08 [debug] 15264#18204: *1 generic phase: 5
2019/08/21 08:11:08 [debug] 15264#18204: *1 generic phase: 6
2019/08/21 08:11:08 [debug] 15264#18204: *1 generic phase: 7
2019/08/21 08:11:08 [debug] 15264#18204: *1 access phase: 8
2019/08/21 08:11:08 [debug] 15264#18204: *1 access phase: 9
2019/08/21 08:11:08 [debug] 15264#18204: *1 access phase: 10
2019/08/21 08:11:08 [debug] 15264#18204: *1 post access phase: 11
2019/08/21 08:11:08 [debug] 15264#18204: *1 generic phase: 12
2019/08/21 08:11:08 [debug] 15264#18204: *1 generic phase: 13
2019/08/21 08:11:08 [debug] 15264#18204: *1 http init upstream, client timer: 0
2019/08/21 08:11:08 [debug] 15264#18204: *1 http script copy: "X-Real-IP"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http script var: "127.0.0.1"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http script copy: "X-Forwarded-For"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http script var: "127.0.0.1"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http script copy: "Host"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http script var: "127.0.0.1"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http script copy: "Connection"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http script copy: "close"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http script copy: ""
2019/08/21 08:11:08 [debug] 15264#18204: *1 http script copy: ""
2019/08/21 08:11:08 [debug] 15264#18204: *1 http proxy header: "User-Agent: PostmanRuntime/7.13.0"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http proxy header: "Accept: */*"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http proxy header: "Cache-Control: no-cache"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http proxy header: "Postman-Token: be0ffd88-6dbb-4eab-b3bb-dc43907a3351"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http proxy header: "accept-encoding: gzip, deflate"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http proxy header:
"GET /api/carnews HTTP/1.0
X-Real-IP: 127.0.0.1
X-Forwarded-For: 127.0.0.1
Host: 127.0.0.1
Connection: close
User-Agent: PostmanRuntime/7.13.0
Accept: */*
Cache-Control: no-cache
Postman-Token: be0ffd88-6dbb-4eab-b3bb-dc43907a3351
accept-encoding: gzip, deflate

"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http cleanup add: 00648F44
2019/08/21 08:11:08 [debug] 15264#18204: *1 init keepalive peer
2019/08/21 08:11:08 [debug] 15264#18204: *1 get keepalive peer
2019/08/21 08:11:08 [debug] 15264#18204: *1 get rr peer, try: 1
2019/08/21 08:11:08 [debug] 15264#18204: *1 stream socket 592
2019/08/21 08:11:08 [debug] 15264#18204: *1 connect to 127.0.0.1:3000, fd:592 #2
2019/08/21 08:11:08 [debug] 15264#18204: *1 select add event fd:592 ev:0
2019/08/21 08:11:08 [debug] 15264#18204: *1 select add event fd:592 ev:1
2019/08/21 08:11:08 [debug] 15264#18204: *1 http upstream connect: -2
2019/08/21 08:11:08 [debug] 15264#18204: *1 malloc: 0097DE58:128
2019/08/21 08:11:08 [debug] 15264#18204: *1 event timer add: 592: 60000:2978232939
2019/08/21 08:11:08 [debug] 15264#18204: *1 http finalize request: -4, "/api/carnews?" a:1, c:2
2019/08/21 08:11:08 [debug] 15264#18204: *1 http request count:2 blk:0
2019/08/21 08:11:08 [debug] 15264#18204: *1 post event 00695648
2019/08/21 08:11:08 [debug] 15264#18204: *1 delete posted event 00695648
2019/08/21 08:11:08 [debug] 15264#18204: *1 http upstream request: "/api/carnews?"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http upstream send request handler
2019/08/21 08:11:08 [debug] 15264#18204: *1 http upstream send request
2019/08/21 08:11:08 [debug] 15264#18204: *1 http upstream send request body
2019/08/21 08:11:08 [debug] 15264#18204: *1 chain writer buf fl:1 s:273
2019/08/21 08:11:08 [debug] 15264#18204: *1 chain writer in: 00648F80
2019/08/21 08:11:08 [debug] 15264#18204: *1 WSASend: fd:592, s:273
2019/08/21 08:11:08 [debug] 15264#18204: *1 chain writer out: 00000000
2019/08/21 08:11:08 [debug] 15264#18204: *1 event timer del: 592: 2978232939
2019/08/21 08:11:08 [debug] 15264#18204: *1 select del event fd:592 ev:1
2019/08/21 08:11:08 [debug] 15264#18204: *1 event timer add: 592: 60000:2978232941
2019/08/21 08:11:08 [debug] 15264#18204: *1 post event 00681640
2019/08/21 08:11:08 [debug] 15264#18204: *1 delete posted event 00681640
2019/08/21 08:11:08 [debug] 15264#18204: *1 http upstream request: "/api/carnews?"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http upstream process header
2019/08/21 08:11:08 [debug] 15264#18204: *1 malloc: 03292020:5242880
2019/08/21 08:11:08 [debug] 15264#18204: *1 WSARecv: fd:592 rc:0 9934 of 5242880
2019/08/21 08:11:08 [debug] 15264#18204: *1 http proxy status 200 "200 OK"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http proxy header: "X-Powered-By: Express"
2019/08/21 08:11:08 [debug] 15264#18204: *1 malloc: 006490C0:4096
2019/08/21 08:11:08 [debug] 15264#18204: *1 http proxy header: "Content-Type: text/html; charset=utf-8"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http proxy header: "Content-Length: 9730"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http proxy header: "ETag: W/"2602-6Rj2eEk783VCSEUpwZPPqxFmOb4""
2019/08/21 08:11:08 [debug] 15264#18204: *1 http proxy header: "Date: Wed, 21 Aug 2019 00:11:08 GMT"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http proxy header: "Connection: close"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http proxy header done
2019/08/21 08:11:08 [debug] 15264#18204: *1 HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Wed, 21 Aug 2019 00:11:08 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 9730
Connection: keep-alive
X-Powered-By: Express
ETag: W/"2602-6Rj2eEk783VCSEUpwZPPqxFmOb4"

2019/08/21 08:11:08 [debug] 15264#18204: *1 write new buf t:1 f:0 006491CC, pos 006491CC, size: 231 file: 0, size: 0
2019/08/21 08:11:08 [debug] 15264#18204: *1 http write filter: l:0 f:0 s:231
2019/08/21 08:11:08 [debug] 15264#18204: *1 http cacheable: 0
2019/08/21 08:11:08 [debug] 15264#18204: *1 http proxy filter init s:200 h:0 c:0 l:9730
2019/08/21 08:11:08 [debug] 15264#18204: *1 http upstream process upstream
2019/08/21 08:11:08 [debug] 15264#18204: *1 pipe read upstream: 0
2019/08/21 08:11:08 [debug] 15264#18204: *1 pipe preread: 9730
2019/08/21 08:11:08 [debug] 15264#18204: *1 pipe buf free s:0 t:1 f:0 03292020, pos 032920EC, size: 9730 file: 0, size: 0
2019/08/21 08:11:08 [debug] 15264#18204: *1 pipe length: 9730
2019/08/21 08:11:08 [debug] 15264#18204: *1 input buf #0
2019/08/21 08:11:08 [debug] 15264#18204: *1 pipe write downstream: 1
2019/08/21 08:11:08 [debug] 15264#18204: *1 pipe write downstream flush in
2019/08/21 08:11:08 [debug] 15264#18204: *1 http output filter "/api/carnews?"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http copy filter: "/api/carnews?"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http postpone filter "/api/carnews?" 006490B0
2019/08/21 08:11:08 [debug] 15264#18204: *1 write old buf t:1 f:0 006491CC, pos 006491CC, size: 231 file: 0, size: 0
2019/08/21 08:11:08 [debug] 15264#18204: *1 write new buf t:1 f:0 03292020, pos 032920EC, size: 9730 file: 0, size: 0
2019/08/21 08:11:08 [debug] 15264#18204: *1 http write filter: l:0 f:0 s:9961
2019/08/21 08:11:08 [debug] 15264#18204: *1 http write filter limit 0
2019/08/21 08:11:08 [debug] 15264#18204: *1 WSASend: fd:588, s:9961
2019/08/21 08:11:08 [debug] 15264#18204: *1 http write filter 00000000
2019/08/21 08:11:08 [debug] 15264#18204: *1 http copy filter: 0 "/api/carnews?"
2019/08/21 08:11:08 [debug] 15264#18204: *1 pipe write downstream done
2019/08/21 08:11:08 [debug] 15264#18204: *1 event timer: 592, old: 2978232941, new: 2978232981
2019/08/21 08:11:08 [debug] 15264#18204: *1 http upstream exit: 00000000
2019/08/21 08:11:08 [debug] 15264#18204: *1 finalize http upstream request: 0
2019/08/21 08:11:08 [debug] 15264#18204: *1 finalize http proxy request
2019/08/21 08:11:08 [debug] 15264#18204: *1 free keepalive peer
2019/08/21 08:11:08 [debug] 15264#18204: *1 free rr peer 1 0
2019/08/21 08:11:08 [debug] 15264#18204: *1 close http upstream connection: 592
2019/08/21 08:11:08 [debug] 15264#18204: *1 free: 0097DE58, unused: 88
2019/08/21 08:11:08 [debug] 15264#18204: *1 event timer del: 592: 2978232941
2019/08/21 08:11:08 [debug] 15264#18204: *1 select del event fd:592 ev:0
2019/08/21 08:11:08 [debug] 15264#18204: *1 reusable connection: 0
2019/08/21 08:11:08 [debug] 15264#18204: *1 http upstream temp fd: -1
2019/08/21 08:11:08 [debug] 15264#18204: *1 http output filter "/api/carnews?"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http copy filter: "/api/carnews?"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http postpone filter "/api/carnews?" 02ECFB64
2019/08/21 08:11:08 [debug] 15264#18204: *1 write new buf t:0 f:0 00000000, pos 00000000, size: 0 file: 0, size: 0
2019/08/21 08:11:08 [debug] 15264#18204: *1 http write filter: l:1 f:0 s:0
2019/08/21 08:11:08 [debug] 15264#18204: *1 http copy filter: 0 "/api/carnews?"
2019/08/21 08:11:08 [debug] 15264#18204: *1 http finalize request: 0, "/api/carnews?" a:1, c:1
2019/08/21 08:11:08 [debug] 15264#18204: *1 set http keepalive handler
2019/08/21 08:11:08 [debug] 15264#18204: *1 http close request
2019/08/21 08:11:08 [debug] 15264#18204: *1 http log handler
2019/08/21 08:11:08 [debug] 15264#18204: *1 free: 03292020
2019/08/21 08:11:08 [debug] 15264#18204: *1 free: 006480B8, unused: 0
2019/08/21 08:11:08 [debug] 15264#18204: *1 free: 006490C0, unused: 3151
2019/08/21 08:11:08 [debug] 15264#18204: *1 free: 006510D0
2019/08/21 08:11:08 [debug] 15264#18204: *1 hc free: 00000000
2019/08/21 08:11:08 [debug] 15264#18204: *1 hc busy: 00000000 0
2019/08/21 08:11:08 [debug] 15264#18204: *1 tcp_nodelay
2019/08/21 08:11:08 [debug] 15264#18204: *1 reusable connection: 1
2019/08/21 08:11:08 [debug] 15264#18204: *1 event timer add: 588: 65000:2978237981
2019/08/21 08:11:27 [debug] 15264#18204: *1 post event 006815F0
2019/08/21 08:11:27 [debug] 15264#18204: *1 delete posted event 006815F0
2019/08/21 08:11:27 [debug] 15264#18204: *1 http keepalive handler
2019/08/21 08:11:27 [debug] 15264#18204: *1 malloc: 006510D0:1024
2019/08/21 08:11:27 [debug] 15264#18204: *1 WSARecv: fd:588 rc:-1 0 of 1024
2019/08/21 08:11:27 [info] 15264#18204: *1 client 127.0.0.1 closed keepalive connection (10054: An existing connection was forcibly closed by the remote host)
2019/08/21 08:11:27 [debug] 15264#18204: *1 close http connection: 588
2019/08/21 08:11:27 [debug] 15264#18204: *1 event timer del: 588: 2978237981
2019/08/21 08:11:27 [debug] 15264#18204: *1 select del event fd:588 ev:0
2019/08/21 08:11:27 [debug] 15264#18204: *1 reusable connection: 0
2019/08/21 08:11:27 [debug] 15264#18204: *1 free: 006510D0
2019/08/21 08:11:27 [debug] 15264#18204: *1 free: 0097DD50, unused: 28

疑问

  • 不知道有没有人这么问(之前发stackoverflow有老外问),你直接请求后端不就ok了,干嘛非要走nginx了.......这个问题我真的没法回答...因为不属于我要问的问题
外国也有不太正常的人,问我为啥不直接连后端,我说为了学习docker,结果他又反问,你这个问题跟docker没关系..........我本来也没说跟docker有关系,只不过在docker运行中发现了这个问题,所以一步一步分离问题,寻求解答.......看来老外也有不靠谱的,正经问题不回答,净想没用的
  • 按照常理,第二个转发数据没显示成功,应该是在error.log中的,但是看了多遍,发现error.log里没任何数据,这就造成了百度google了一圈,因为没特定关键词,搜索了很多方法都没法解决.....没办法,作为中国的stackflow,只好死马当活马医了.........

关注 1 回答 1

wszgrcy 回答了问题 · 2019-07-19

解决VsCode触发代码补全后的代码提示失效问题。

排除文件,貌似emmet干预太多了,可以把ts,js文件排除,就好了
1楼的回答虽然能解决,但是测试了下发现按tab上提示失效了.....

关注 6 回答 5

wszgrcy 发布了文章 · 2019-05-06

ngModel源码浅解

前言

  • 之前看过vue的双向绑定原理,并实现过简易的demo,但是很少见过有讲解angular下,双向绑定是如何实现的,所以看了下NgModel源码,发现大同小异,特来说下
  • 目前来说只说下ngModel是如何实现的,不涉及属性绑定及指令方面的知识
  • 本篇文章需要知道如下知识才可以阅读
自定义表单控件
响应式表单之FormControl

一个ngModel,使用了几个指令?

  • 一般当这么说,那么肯定意味着使用了不只一个指令,否则也不会浪费时间说一个确定的事实
组件也是继承于指令的,所以这么说应该也不算错
  • NgModelControlValueAccessor实现类,当你要使用NgModel时,实际上是使用了两个指令
  • NgModel 负责注册一些函数,所有ControlValueAccessor实现类实现的4个方法(一个可选禁用方法),最终都是通过NgModel的来使用的
  • ControlValueAccessor实现类是规定绑定的内部逻辑,比如什么时候发送值被变更,当出现值写入时如何处理

流程示意图

图

注册

  • 所谓注册就是当值变更时.实现类应该用哪些方法去通知已经变更
  • 实现类中的registerOnChange(fn),fn就是在注册阶段传入的,当在这个阶段调用实现类.registerOnChange(fn),函数被赋值到实现类中,而当值变更时实现类则调用此函数通知值已变更
  • 此阶段,总共有6个方法被注册(验证器分为同步,异步)
  1. 实现类中registerOnChange,当视图中值发生了变更调用传入函数
  2. 实现类中registerOnTouched,默认中的实现类是当失去焦点调用传入函数
  3. NgModel中FormControl实例中registerOnChange,当值变化是调用传入函数
  4. NgModel中FormControl实例中registerOnDisabledChange,禁用状态变化时,调用实现类中的setDisabledState方法
  5. 验证器的registerOnValidatorChange当验证器的输入属性变化时调用传入函数
  • 传入函数已经写在shared.ts文件中

输入

  • 当[ngModel]传入的值变更后会被NgModelngOnchanges钩子捕获到
  • 如果值变更或为初始值,那么会调用钩子中的this._updateValue(this.model)
  • 此方法会触发类中FormControl实例的值变更
  • 当值变更时,上述注册方法中的3会执行传入函数,函数中会触发实现类中的writeValue方法,此时实现类收到了变更值
  • 在默认的方法中,收到变更值后,是利用angular的渲染器,写入到input元素的value中
  • 输入流程结束

输出

  • inputcompositionend事件时,会调用传入函数onChange.当blur事件时,会调用传入函数onTouched
  • 函数收到值后判断是不是处在更新时机,如果是那么更新调用NgModel中的viewToModelUpdate
  • 此方法更新值并发射信号ngModelChange告知值已经变更

难点

  • 大家应该都知道自定义表单控件怎么写,明明没有写过ngModel input属性和ngModelChange output事件,但是却在实现了ControlValueAccessor类后神奇的实现了.
  • 这里其实就是因为NgModel指令的选择器是[ngModel]:not([formControlName]):not([formControl]),也就是说,只要不是响应式表单,那么所有带ngModel的都会自动使用这个指令
  • 并且该指令在构造时会找他的ControlValueAccessor实现类,当找到后,通过将一些变更需要出发的函数告知实现类而建立了关联

源码注释

疑问

  • 如果有哪里描述的有问题或者不对的请多提宝贵意见
查看原文

赞 0 收藏 0 评论 0

wszgrcy 发布了文章 · 2019-05-06

ngModel源码浅解

前言

  • 之前看过vue的双向绑定原理,并实现过简易的demo,但是很少见过有讲解angular下,双向绑定是如何实现的,所以看了下NgModel源码,发现大同小异,特来说下
  • 目前来说只说下ngModel是如何实现的,不涉及属性绑定及指令方面的知识
  • 本篇文章需要知道如下知识才可以阅读
自定义表单控件
响应式表单之FormControl

一个ngModel,使用了几个指令?

  • 一般当这么说,那么肯定意味着使用了不只一个指令,否则也不会浪费时间说一个确定的事实
组件也是继承于指令的,所以这么说应该也不算错
  • NgModelControlValueAccessor实现类,当你要使用NgModel时,实际上是使用了两个指令
  • NgModel 负责注册一些函数,所有ControlValueAccessor实现类实现的4个方法(一个可选禁用方法),最终都是通过NgModel的来使用的
  • ControlValueAccessor实现类是规定绑定的内部逻辑,比如什么时候发送值被变更,当出现值写入时如何处理

流程示意图

图

注册

  • 所谓注册就是当值变更时.实现类应该用哪些方法去通知已经变更
  • 实现类中的registerOnChange(fn),fn就是在注册阶段传入的,当在这个阶段调用实现类.registerOnChange(fn),函数被赋值到实现类中,而当值变更时实现类则调用此函数通知值已变更
  • 此阶段,总共有6个方法被注册(验证器分为同步,异步)
  1. 实现类中registerOnChange,当视图中值发生了变更调用传入函数
  2. 实现类中registerOnTouched,默认中的实现类是当失去焦点调用传入函数
  3. NgModel中FormControl实例中registerOnChange,当值变化是调用传入函数
  4. NgModel中FormControl实例中registerOnDisabledChange,禁用状态变化时,调用实现类中的setDisabledState方法
  5. 验证器的registerOnValidatorChange当验证器的输入属性变化时调用传入函数
  • 传入函数已经写在shared.ts文件中

输入

  • 当[ngModel]传入的值变更后会被NgModelngOnchanges钩子捕获到
  • 如果值变更或为初始值,那么会调用钩子中的this._updateValue(this.model)
  • 此方法会触发类中FormControl实例的值变更
  • 当值变更时,上述注册方法中的3会执行传入函数,函数中会触发实现类中的writeValue方法,此时实现类收到了变更值
  • 在默认的方法中,收到变更值后,是利用angular的渲染器,写入到input元素的value中
  • 输入流程结束

输出

  • inputcompositionend事件时,会调用传入函数onChange.当blur事件时,会调用传入函数onTouched
  • 函数收到值后判断是不是处在更新时机,如果是那么更新调用NgModel中的viewToModelUpdate
  • 此方法更新值并发射信号ngModelChange告知值已经变更

难点

  • 大家应该都知道自定义表单控件怎么写,明明没有写过ngModel input属性和ngModelChange output事件,但是却在实现了ControlValueAccessor类后神奇的实现了.
  • 这里其实就是因为NgModel指令的选择器是[ngModel]:not([formControlName]):not([formControl]),也就是说,只要不是响应式表单,那么所有带ngModel的都会自动使用这个指令
  • 并且该指令在构造时会找他的ControlValueAccessor实现类,当找到后,通过将一些变更需要出发的函数告知实现类而建立了关联

源码注释

疑问

  • 如果有哪里描述的有问题或者不对的请多提宝贵意见
查看原文

赞 0 收藏 0 评论 0

wszgrcy 关注了用户 · 2018-04-22

电波马达 @sane

关注 110

wszgrcy 关注了用户 · 2018-04-22

黑_白 @carlo

关注 1311

认证与成就

  • 获得 0 次点赞
  • 获得 3 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 3 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2018-04-22
个人主页被 257 人浏览