@carlchen
2017-05-31T08:25:35.000000Z
字数 5984
阅读 1129
编程语言
let myfun: (value:number, index:number, arr:number[])=>void;
function fun(value: number){
return value * 100;
}
myfun = fun;
如上所示,给函数类型变量赋值的函数,可以少一些参数,而且如果函数类型的返回值是void,实际赋值的函数可以返回任意类型。
总之,函数就像一个员工, 函数的参数是员工提的要求,函数的返回值是员工的工作成果。如果一个员工 少提要求,多出成果,大家都喜欢,不会报错。但是反过来就不行, 一个员工多提要求,提不同的要求,不出成果(或出的成果不符合要求),都是不允许的。
这个和可选参数是不一样的,不要混淆了。
进入配置文件后,就可以编写sinppet了。
snippet 由三部分组成:
其中 body 部分可以使用特殊结构来控制光标和要插入的文本。 支持的功能及其文法如下:
"#ifndef $1"
"#define $1"
"#end // $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:当前文档的完整文件路径
注意,这些都是变量名,不是宏,在实际使用的时候还是要加上$符的。
Easy Snippet Maker 可以让你在选中的文本上右键,选择“create code snippet”, 把选中的文本自动写入到配置文件。当然,你还需要指定 snippet的名称、缩写和说明文字。
模板的数据绑定形式有如下四种
严格来说,只有两种形式是真实的,即属性绑定和事件绑定,另外两种只是方便写代码而提供的语法糖。 所以,重点理解属性和事件绑定。这两种绑定都是单向的、简单的。
用户名:<input [value]="userName" type="text">
<br>
密码:<input [value]="passWord" type="password">
上面两个 input 标签的 value 属性分别被绑定到组件的 userName 和 passWord 成员变量上,具体的含义就是当成员变量的值被改变时,input控件的显示值也会跟着变化,这个过程是自动完成的,并且是单向的,即从组件成员变量传递给界面元素。
属性绑定的左边,中括号内是HTML标签的属性,也可以是其他指令提供的属性(记住,指令是用来增强标签的功能的,它会给标签增加一些 属性、可绑定的属性、事件)。比如下面代码,myDirective是一个指令(准确的说是指令选择符),它提供了两个可绑定的属性 toolTip 和 toolTipColor。
<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标签属性的初始化,但是我们不建议这样写,如果别人写了,能看懂就行。
<input #inputRef [value]="userName" (change)="inputOnChange($event);" type="text">
上面的input输入框,当用户输入完内容,按下回车键或者离开输入框时,会引发change事件(就是表示输入框的内容被用户改变了的意思),引发了change事件,就会执行绑定在该事件上的语句,注意,这里是语句。所以,您可以把好几个语句一起绑定到一个事件上,语句之间用分号分隔。
事件绑定也是单向的, 即从界面元素引发语句的执行,这些语句执行的上下文在组件内部,所以可以直接调用组件的成员函数和变量。语句的上下文除了组件,还有事件对象和模板中定义的模板局部变量。
如上代码中,$event 是事件对象 ,它是在change事件被引发时被传递过来的,您可以在语句中使用它,也可以完全不予理会。具体的$event是怎样一个对象呢?不同的事件会传递不同的对象,您可以用console.log()输出这个对象来看看其内容,具体的做法是在inputOnChagne函数内部输出,如下所示:
inputOnChange(event_object: any){
console.log(event_object);
}
那为什么不直接在change事件绑定时写成(change)="console.log($event);" ,这个想法非常好,可是console.log函数在组件上下文中找不到,所以不能这样写。
在这里,我告诉大家 change事件传递的$event 有一个target成员属性,这个target表示的就是引发change事件的对象自身,在这里就是input标签本身,所以$event.target.value 表示的是change事件引发时,input控件所显示的值。因此我们可以改写代码为如下:
<input #inputRef [value]="userName" (change)="userName = $event.target.value" type="text">
这样,就在change事件引发时(即当用户按下回车键或离开输入框时),输入框的内容被赋值给了组件的userName成员变量。
我们再来说说事件绑定的语句中可以使用的另一个上下文,即模板局部变量。如上代码中,inputRef就是模板局部变量,在这里inputRef代表了input控件本身,因此我们可以改写代码如下,来实现输入完毕后清空输入框的功能。
<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标签内部的内容绑定一些值,怎么办呢? 这就需要采用叫做"插值"的模板语法了。如下:
<i>Hello, {{userName}}</i>
<i>hello, </i><i [innerHTML]="userName"></i>
上面代码的第一行就是插值模板语法,就是用双花括号把表达式包围起来就可以了,这里的表达式和属性绑定使用的表达式是一样的。
上面代码的第二行和第一行是等效的。所以,您可以知道,插值其实是属性绑定的一种简写,这种简写使得代码的可读性更好,并且减少了不必要的字符串拼接操作。
如果您了解HTML5,您就知道innerHTML这个DOM属性代表的就是HTML标签的内容。
其实,上面在介绍完了事件绑定后,您应该就能够自己实现“双向绑定”的功能了,比如下面的代码:
<input [value]="userName" (change)="userName = $event.target.value" type="text">
这段代码就已经把userName和input控件进行了双向绑定。即 userName被改变时,通过属性绑定,userName的值被反映到input控件上。input控件被用户输入一些文字,并按下回车键或退出时,引发了change事件,此时执行事件绑定的语句,控件的当前值(即用户已经输入的文字)就被赋值给了userName这个成员变量。所以,这就是双向绑定的正真运行机理。
这里有个小问题,就是change事件是在按下回车或离开时才引发的,如果我想要每输入一个字母都引发事件呢。提出这个问题,证明您是一个有理想有抱负的青年。好吧,input事件就正好是您想要的那个。
但是,上面的写法略显繁琐,不是吗!
幸运的是Angualr2的创造者也这样认为,于是,为了让我们这些开发者更愉快的使用,他们又开始发糖了,不是喜糖哈,是语法糖!
这就是本节要介绍的中括号嵌套小括号语法,[(属性名)]="变量名",是不是很感性、很形象啊!
好吧!为了使用这个双向绑定语法,是有一定条件的,具体条件如下:
假如我们的input标签的value属性具备上面的两个条件,那么我们就可以将双向绑定写成下面的形式:
<input [(value)]="userName" type="text">
很简洁很爽!有没有!
别高兴太早。我们只是假设value可以这样而已,实际上input的value不具备上面两个条件。
这个时候就轮到NgModel指令隆重登场了。
<input [(ngModel)]="userName" type="text">
<input ngModel [ngModel]="userName" (ngModelChange)="userName = $event" type="text">
请看第一行代码,是不是已经达到了我们对极致简洁的追求呢?啊哈哈!
第二行代码是第一行代码的展开形式,与第一行等效。
我们来分析一下第二行代码,其中第一个ngModel是为input标签引入NgModel指令(它的正规名字叫指令选择符),第二个ngModel在中括号内,他是NgModel指令的一个属性名,被绑定到userName上,ngModelChange是一个事件名称,它的事件对象就是input的value值。
这里,您可能奇怪为什么指令选择符合和指令的一个属性同名,我能告诉您他们是故意的吗? 好吧!他们就是故意这样弄的,好让您可以省略指令选择符,从而写出像第一行这样简洁的代码。
NgModel关于双向绑定的内容就介绍完了,但是它不仅仅提供了这些内容,它还具有验证用户输入、提供各种样式、和NgForm等指令配合使用等功能,具体这里暂不介绍。
为了进一步理解NgModel和属性型指令的原理,请阅读下面的参考链接,获得更多的信息。
Angular2中文文档-属性型指令介绍