[关闭]
@carlchen 2017-05-31T08:25:35.000000Z 字数 5984 阅读 1129

TypeScript 笔记

编程语言


函数类型变量(以及回调函数)的匹配问题

  1. let myfun: (value:number, index:number, arr:number[])=>void;
  2. function fun(value: number){
  3. return value * 100;
  4. }
  5. myfun = fun;

如上所示,给函数类型变量赋值的函数,可以少一些参数,而且如果函数类型的返回值是void,实际赋值的函数可以返回任意类型。

总之,函数就像一个员工, 函数的参数是员工提的要求,函数的返回值是员工的工作成果。如果一个员工 少提要求,多出成果,大家都喜欢,不会报错。但是反过来就不行, 一个员工多提要求,提不同的要求,不出成果(或出的成果不符合要求),都是不允许的。
这个和可选参数是不一样的,不要混淆了。


TypeScript编码风格

不要使用null

image.png-15.6kB

不要使用for in语句

image.png-103.5kB

代码样式风格

  1. 使用arrow函数代替匿名函数表达式。
  2. 只要需要的时候才把arrow函数的参数括起来。
    比如, (x) => x + x 是错误的,下面是正确的做法:
    image.png-11.2kB
  3. 总是使用 {} 把循环体和条件语句括起来。
  4. 开始的 { 总是在同一行。
  5. 小括号里开始不要有空白.
    逗号,冒号,分号后要有一个空格。比如:
    image.png-23.7kB
  6. 每个变量声明语句只声明一个变量
    (比如 使用 var x = 1; var y = 2; 而不是 var x = 1, y = 2; )。
  7. else 要在结束的 } 后另起一行。

VS Code 使用笔记

Sinppets编写

打开配置文件的方式

  1. 菜单: 通过文件 > 首选项 > 用户代码片段,选择进入目的语言的代码段设置文件
  2. 命令:通过快捷键[Ctrl + Shift + P]打开命令窗口(all command window),输入[snippet],通过候选栏中的选项进入目的语言的代码段设置文件

进入配置文件后,就可以编写sinppet了。

配置文件组成

snippet 由三部分组成:

body部分编写

其中 body 部分可以使用特殊结构来控制光标和要插入的文本。 支持的功能及其文法如下:

  1. "#ifndef $1"
  2. "#define $1"
  3. "#end // $1"
  1. struct ${1:name_t} {\n\t$2\n};

作为[Placeholder]的name_t一方面可以提供默认的结构名称,另一方面可以作为输入的提示。

使用$name或${name:default}可以插入变量的值。 当未设置变量时,将插入其缺省值或空字符串。 当varibale未知(即,其名称未定义)时,将插入变量的名称,并将其转换为[placeholder]。 可以使用以下[Variable]:

TM_SELECTED_TEXT:当前选定的文本或空字符串
TM_CURRENT_LINE:当前行的内容
TM_CURRENT_WORD:光标下的单词的内容或空字符串
TM_LINE_INDEX:基于零索引的行号
TM_LINE_NUMBER:基于一索引的行号
TM_FILENAME:当前文档的文件名
TM_DIRECTORY:当前文档的目录
TM_FILEPATH:当前文档的完整文件路径

注意,这些都是变量名,不是宏,在实际使用的时候还是要加上$符的。

官方给出的snippet正则文法

VSCode 的 snippet 插件

Easy Snippet Maker 可以让你在选中的文本上右键,选择“create code snippet”, 把选中的文本自动写入到配置文件。当然,你还需要指定 snippet的名称、缩写和说明文字。

Easy Snippet Maker


Angular2 笔记

数据绑定的形式

模板的数据绑定形式有如下四种

严格来说,只有两种形式是真实的,即属性绑定和事件绑定,另外两种只是方便写代码而提供的语法糖。 所以,重点理解属性和事件绑定。这两种绑定都是单向的、简单的。

属性绑定(用中括号表示)

  1. 用户名:<input [value]="userName" type="text">
  2. <br>
  3. 密码:<input [value]="passWord" type="password">

上面两个 input 标签的 value 属性分别被绑定到组件的 userName 和 passWord 成员变量上,具体的含义就是当成员变量的值被改变时,input控件的显示值也会跟着变化,这个过程是自动完成的,并且是单向的,即从组件成员变量传递给界面元素

属性绑定的左边,中括号内是HTML标签的属性,也可以是其他指令提供的属性(记住,指令是用来增强标签的功能的,它会给标签增加一些 属性、可绑定的属性、事件)。比如下面代码,myDirective是一个指令(准确的说是指令选择符),它提供了两个可绑定的属性 toolTip 和 toolTipColor。

  1. <input myDirective [toolTip]="userName" [toolTipColor]="'orange'" type="text">

属性绑定的右边,是用双引号(当然也可以用单引号,但建议保持一致,请坚持都用双引号)括起来的表达式。注意这里是表达式,绝大多数javascript的表达式都可以使用。因此,上面代码中,[toolTipColor]="'orange'" 是表示把'orange'这个字符串绑定到toolTipColor上,所以结果是一个固定的字符串,假如您写的是 [toolTipColor]="orange" ,则表示是把组件的 orange这个成员变量绑定到toolTipColor上,结果是,具体的颜色值会根据orange变量的值而变化。

顺便提一下,如果您要绑定true、false或者数字给属性的话,要写[isVisible]="true" 或者 [value]="120" ,请考虑下为什么这样写?
属性绑定也可以不用写中括号,比如上面的 [toolTipColor]="'orange'" 可以简写成 toolTipColor="orange",类似于普通的HTML标签属性的初始化,但是我们不建议这样写,如果别人写了,能看懂就行。

事件绑定(用小括号表示)

  1. <input #inputRef [value]="userName" (change)="inputOnChange($event);" type="text">

上面的input输入框,当用户输入完内容,按下回车键或者离开输入框时,会引发change事件(就是表示输入框的内容被用户改变了的意思),引发了change事件,就会执行绑定在该事件上的语句,注意,这里是语句。所以,您可以把好几个语句一起绑定到一个事件上,语句之间用分号分隔。

事件绑定也是单向的, 即从界面元素引发语句的执行,这些语句执行的上下文在组件内部,所以可以直接调用组件的成员函数和变量。语句的上下文除了组件,还有事件对象和模板中定义的模板局部变量
如上代码中,$event 是事件对象 ,它是在change事件被引发时被传递过来的,您可以在语句中使用它,也可以完全不予理会。具体的$event是怎样一个对象呢?不同的事件会传递不同的对象,您可以用console.log()输出这个对象来看看其内容,具体的做法是在inputOnChagne函数内部输出,如下所示:

  1. inputOnChange(event_object: any){
  2. console.log(event_object);
  3. }

那为什么不直接在change事件绑定时写成(change)="console.log($event);" ,这个想法非常好,可是console.log函数在组件上下文中找不到,所以不能这样写。

在这里,我告诉大家 change事件传递的$event 有一个target成员属性,这个target表示的就是引发change事件的对象自身,在这里就是input标签本身,所以$event.target.value 表示的是change事件引发时,input控件所显示的值。因此我们可以改写代码为如下:

  1. <input #inputRef [value]="userName" (change)="userName = $event.target.value" type="text">

这样,就在change事件引发时(即当用户按下回车键或离开输入框时),输入框的内容被赋值给了组件的userName成员变量。

我们再来说说事件绑定的语句中可以使用的另一个上下文,即模板局部变量。如上代码中,inputRef就是模板局部变量,在这里inputRef代表了input控件本身,因此我们可以改写代码如下,来实现输入完毕后清空输入框的功能。

  1. <input #inputRef [value]="userName" (change)="userName = $event.target.value; inputRef.value='';" type="text">

这只是一个小例子,可以用模板局部变量很炫酷的html模板,开启您的想象力吧!

属性绑定和事件绑定的具体形式不仅仅有中括号、小括号,还可以用前缀的方式,如 bind-value="userName" 和 [value]="userName" 是等价的。on-change="inputOnChange($event);" 和 (change)="inputOnChange($event);" 是等价的。
我们建议在您的程序中采用统一的一种方式,混用的话容易引起麻烦,强烈建议一直采用括号形式

插值(用双花括号表示)

介绍过了属性绑定。但是,很多时候我们需要给HTML标签内部的内容绑定一些值,怎么办呢? 这就需要采用叫做"插值"的模板语法了。如下:

  1. <i>Hello, {{userName}}</i>
  2. <i>hello, </i><i [innerHTML]="userName"></i>

上面代码的第一行就是插值模板语法,就是用双花括号把表达式包围起来就可以了,这里的表达式和属性绑定使用的表达式是一样的。
上面代码的第二行和第一行是等效的。所以,您可以知道,插值其实是属性绑定的一种简写,这种简写使得代码的可读性更好,并且减少了不必要的字符串拼接操作。

如果您了解HTML5,您就知道innerHTML这个DOM属性代表的就是HTML标签的内容。

双向绑定(用中括号嵌套小括号表示)

其实,上面在介绍完了事件绑定后,您应该就能够自己实现“双向绑定”的功能了,比如下面的代码:

  1. <input [value]="userName" (change)="userName = $event.target.value" type="text">

这段代码就已经把userName和input控件进行了双向绑定。即 userName被改变时,通过属性绑定,userName的值被反映到input控件上。input控件被用户输入一些文字,并按下回车键或退出时,引发了change事件,此时执行事件绑定的语句,控件的当前值(即用户已经输入的文字)就被赋值给了userName这个成员变量。所以,这就是双向绑定的正真运行机理。

这里有个小问题,就是change事件是在按下回车或离开时才引发的,如果我想要每输入一个字母都引发事件呢。提出这个问题,证明您是一个有理想有抱负的青年。好吧,input事件就正好是您想要的那个。

但是,上面的写法略显繁琐,不是吗!
幸运的是Angualr2的创造者也这样认为,于是,为了让我们这些开发者更愉快的使用,他们又开始发糖了,不是喜糖哈,是语法糖!
这就是本节要介绍的中括号嵌套小括号语法,[(属性名)]="变量名",是不是很感性、很形象啊!
好吧!为了使用这个双向绑定语法,是有一定条件的,具体条件如下:

  1. HTML标签(或者说是控件、组件)应该具有名叫 属性名 的属性以及具有名叫 属性名Change 的事件。
  2. 属性名Change 事件的事件对象(即$event)是一个简单的值,就是那个您需要的值,而不是其他更复杂的对象。

假如我们的input标签的value属性具备上面的两个条件,那么我们就可以将双向绑定写成下面的形式:

  1. <input [(value)]="userName" type="text">

很简洁很爽!有没有!
别高兴太早。我们只是假设value可以这样而已,实际上input的value不具备上面两个条件。
这个时候就轮到NgModel指令隆重登场了。

NgModel指令

  1. <input [(ngModel)]="userName" type="text">
  2. <input ngModel [ngModel]="userName" (ngModelChange)="userName = $event" type="text">

请看第一行代码,是不是已经达到了我们对极致简洁的追求呢?啊哈哈!
第二行代码是第一行代码的展开形式,与第一行等效。

我们来分析一下第二行代码,其中第一个ngModel是为input标签引入NgModel指令(它的正规名字叫指令选择符),第二个ngModel在中括号内,他是NgModel指令的一个属性名,被绑定到userName上,ngModelChange是一个事件名称,它的事件对象就是input的value值。

这里,您可能奇怪为什么指令选择符合和指令的一个属性同名,我能告诉您他们是故意的吗? 好吧!他们就是故意这样弄的,好让您可以省略指令选择符,从而写出像第一行这样简洁的代码。

NgModel关于双向绑定的内容就介绍完了,但是它不仅仅提供了这些内容,它还具有验证用户输入、提供各种样式、和NgForm等指令配合使用等功能,具体这里暂不介绍。

为了进一步理解NgModel和属性型指令的原理,请阅读下面的参考链接,获得更多的信息。
Angular2中文文档-属性型指令介绍

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注