KnockoutJs学习笔记(五)

做为一名初学者来讲,一篇篇的按顺序看官网上的文档的确是一件很痛苦的事情,毕竟它的排列也并不是是由浅及深的排列,其中的顺序也颇回味无穷,因而这篇文章我又跳过了Reference部分,进而进入到具体的bindings环节,首先接触到的是Controlling text and appearance。javascript


Visible binding会依据绑定的数据来决定相应的DOM元素是否隐藏。css

咱们首先在js文件部分定义一个view model,这里我建立的是一个object而不是一个构造函数,我的分析认为,object类型的定义就是一种persistent view model,而构造函数类型的定义就是一种temporary view model,这个也许和pure computed observables中的性能有关,可和knockout学习笔记(四)联系起来。html

相应的js部分以下:java

1 var myViewModel = {
2   shouldShowMessage: ko.observable()
3 }
4 
5 ko.applyBindings(myViewModel);

在html部分的测试元素以下:web

1 <p data-bind="visible: shouldShowMessage">Test for visible binding</p>

在这种状况下,因为我没有给shouldShowMessage赋一个初始值,因此应该是undefined,即对应的false,实际上页面显示出来的是:安全

能够看出咱们添加的p元素并无显示出来,接下来我在js部分修改了shouldShowMessage的值:app

1 myViewModel.shouldShowMessage(true);

页面变成了这样:函数

此时的页面中显示出了p元素。性能

有关visible binding的参数:当参数是false或至关于false的值时,binding会将yourElement.style.display设置为none使得订阅的元素隐藏,而这个设定也会覆盖掉全部你本身定义的CSS样式,我猜想这是和CSS样式覆盖规则有关,knockoutjs也许就是将这一个赋值的优先级设置为最高或者是合理利用了相应的顺序,这个能够之后研究knockoutjs的源码的时候查一查。当参数是true或是至关于true的值时,binding会删去相应的yourElement.style.display,从而让用户自定义的CSS样式做用于订阅的元素上。学习

当参数是一个observable时,每当参数变化,UI部分的元素都会更新本身的visible属性,而当参数不是observable时,UI部分的元素只会对visible属性设定一次。固然,参数也能够是一个函数,binding会根据function返回的值是true仍是false来决定是否显示相应的DOW element。


Text binding会使得相应的DOM element的text部分变为参数的值。

js部分的代码以下:

1 var myViewModel = {
2   myText: ko.observable()
3 }
4 
5 ko.applyBindings(myViewModel);
6 
7 myViewModel.myText("Hello world!");

html部分的代码以下:

1 <p>This is my text: <span data-bind="text: myText"></span></p>

页面显示效果以下:

利用text binding的时候,element所订阅的view model的值会覆盖掉html中现有的text部分,若是参数是一个observable,每当参数变化的时候,UI都会更新本身的text部分,而若是参数不是observable,UI只会在最初的时候设定好text,之后再也不更新。若是参数不是数字类型也不是字符串类型,则binding会调用yourParameter.toString()来将其转换为text再替换掉text部分的内容。

注意一:若是咱们但愿经过函数来计算或者说控制输出到text部分的值,咱们能够将其绑定至一个computed observable,js部分以下:

 1 var myViewModel = {
 2   myText: ko.observable(),
 3   myComputed: ko.pureComputed(function() {
 4     return myViewModel.myText() > 50 ? "Big" : "Small";
 5   })
 6 }
 7 
 8 ko.applyBindings(myViewModel);
 9 
10 myViewModel.myText(60);

html部分以下:

1 <p>This is my text: <span data-bind="text: myComputed"></span></p>

页面效果以下:

在上例中的view model是做为object直接声明的,这是为了可以方便地更改其中的属性(myText)。若是将上例中的myViewModel.myText替换为this.myText,必然会报错,由于以前的文章已经提到过,function并不能算做是object的一部分,不过computed提供了一个指定this的值的方式,若是修改为如下模样:

1 var myViewModel = {
2   myText: ko.observable(),
3   myComputed: ko.pureComputed(function() {
4     return this.myText() > 50 ? "Big" : "Small";
5   }, this)
6 }

结果依然会报错:undefined is not a function。这里也许须要理清的就是函数中的this和object中的this的问题,留做之后研究。以后我换了一种方式,换成了构造函数:

1 function MyViewModel(myText) {
2   this.myText = ko.observable(myText);
3   this.myComputed = ko.pureComputed(function() {
4     return this.myText() > 50 ? "Big" : "Small";
5   }, this);
6 }

这样是可行的,我就猜测会不会是以前的例子里没有给属性添加this,经测试,object里面彻底不支持this,这也是本身对javascript的理解不清晰所致,因而能够认为,在object的定义形式中,computed内所关联的observable需带上这个view model的全名,而在function的定义形式中,则可使用this来指代当前的实例。这里又涉及到这两种定义方式的区别问题,留做之后研究

固然,咱们也能够直接将computed部分最后返回的结果用data-bind来绑定,以下:

1 <p>This is my text: <span data-bind="text: myText > 50 ? 'Big' : 'Small'"></span></p>

这样咱们就不须要再定义一个computed observable。

注意二:若是咱们传入text的参数中含有html的标签,页面中并不会将其以标签的形式展示,而是会以字符串的方式展示出来,例如:

1 myViewModel.myText("<i>Hello world!</i>");

显示出来会是:

这样也能够防止HTML或是script的注入攻击。而有关html标签的绑定则须要参考html binding。

注意三:在某些时候,咱们须要在不指定元素的状况下直接插入text,此时咱们可使用无容器的语法来定义一个text binding。例如在option element中是不容许包含其余元素的,若是咱们以下定义data-bind

1 <select>
2 <option>Item <span data-bind="text: myText"></span></option>
3 </select>

咱们并不能获得view model中的observable,无容器的语法则是这样写的:

1 <select>
2 <option>Item <!--ko text: myText--><!--/ko--></option>
3 </select>

<!--ko-->和<!--/ko-->扮演着开始标志和结束标志,它们定义了一个虚拟元素,knockout语法可以理解这种写法并像对待一个最真实元素那样去绑定相应的view model内的值。


Html binding其实与text binding相似,只不过它的参数通常是带有html标签的,这样就能够自定义想要绑定的html元素。

下面是个很简单的例子:

1 var myViewModel = {
2   myHtml: ko.observable(),
3 }
4 
5 ko.applyBindings(myViewModel);
6 
7 myViewModel.myHtml("<a href='http://www.google.com'>Google</a>");

html部分以下:

1 <p>My html element is: <span data-bind="html: myHtml"></span></p>

页面的效果以下:

html binding的其余特性与text binding相似,可是使用html binding的时候要特别注意安全问题,防止注入式攻击等。


CSS binding主要用于根据view model的修改来更改UI中相应元素的class,从而依照CSS文件中已经定义好的样式来体如今页面中。一个简单的static css binding例子以下:

js部分:

1 var myViewModel = {
2   myTest : ko.observable(),
3 }
4 
5 ko.applyBindings(myViewModel);
6 
7 myViewModel.myTest(20);

html部分:

1 <p data-bind="css: { redText: myTest() > 0 }">Test for css binding</p>

css部分:

1 .redText {
2   color: red;
3 }

页面显示效果以下:

另外,咱们也能够经过绑定一个computed observable来动态指定css class的值,这样的绑定称为dynamic css binding,简单的例子以下:

js部分:

 1 var myViewModel1 = {
 2   myTest: ko.observable(),
 3   myComputed: ko.pureComputed(function() {
 4     return myViewModel1.myTest() > 0 ? "redText" : "blueText";
 5   })
 6 };
 7     
 8 var myViewModel2 = {
 9   myTest: ko.observable(),
10   myComputed: ko.pureComputed(function() {
11     return myViewModel2.myTest() > 0 ? "redText" : "blueText";
12   })
13 };
14 
15 ko.applyBindings(myViewModel1, document.getElementById("redText"));
16 ko.applyBindings(myViewModel2, document.getElementById("blueText"));
17 
18 myViewModel1.myTest(20);
19 myViewModel2.myTest(-20);

html部分:

1 <p id="redText" data-bind="css: myComputed">This is red text.</p>
2 <p id="blueText" data-bind="css: myComputed">This is blue text.</p>

css部分:

1 .redText {
2     color: red;
3 }
4 
5 .blueText {
6     color: blue;
7 }

页面显示效果以下:

 css bidning是十分灵活的,对于static css binding,咱们通常是以data-bind="css: {cssClass: viewModelProperty}"的形式来绑定css class,cssClass会根据viewModelProperty返回的值是true仍是false来决定这个class如今是否须要使用。另外,咱们也能够一次性设置多个css classes,简单的示例以下:

js部分:

1 var myViewModel = {
2   redTextDecision: ko.observable(),
3   textDecorationDecision: ko.observable()
4 };
5 
6 ko.applyBindings(myViewModel);
7 
8 myViewModel.redTextDecision(true);
9 myViewModel.textDecorationDecision(true);

html部分:

1 <p data-bind="css: {redText: redTextDecision, textDecoration: textDecorationDecision}">This is red text, and its text-decoration is underline.</p>

css部分:

1 .redText {
2   color: red;
3 }
4 
5 .textDecoration {
6   text-decoration: underline;
7 }

页面显示效果以下:

在上例中,咱们是使用两个view model的property来决定两个不一样的css class,KO也容许咱们使用一个view model property来决定多个css class,可将上例的html部分改为以下形式:

1 <p data-bind="css: {'redText textDecoration': redTextDecision}">This is red text, and its text-decoration is underline.</p>

这里为了简便,并无更改相应的view model property的名称,能够看到,当对多个css class进行设定的时候,咱们须要将它们统一包含在引号中。

若是绑定的view model property属性是一个observable,则UI会根据该observable的变化来动态的增长或删去被绑定的css class,不然,UI只会在开始阶段设定一次css class,以后再也不更新。

dynamic css binding的通常形式是这样的:data-bind="css: viewModelProperty",UI会根据viewModelProperty返回的字符串(property自己能够是一个表明css class的字符串)来决定添加的css class的名称。若是property是一个observable,则在该observable改变的时候,UI会删去以前该observable所添加的class并从新设置为当前observable的值。在dynamic css binding中,咱们可让viewModelProperty添加多个css class,只需将这些css class以空格分开并统一以字符串的方式返回便可。一个简单的例子以下:

js部分:

1 var myViewModel = {
2   textDecorationDecision: ko.observable("textDecoration redText")
3 };
4 
5 ko.applyBindings(myViewModel);

html部分:

1 <p data-bind="css: textDecorationDecision">This is red text, and its text-decoration is underline.</p>

页面显示效果以下:

对于某些带有特殊符号的css class,好比red-text,咱们不能直接在data-bind中以data-bind="css: {red-text: redTextDecision}"的方式来设定,而是应该在这类css class外添加一对引号使其成为字符串常量,变成这样:data-bind="css: {'red-text': redTextDecision}"。


style binding是与css binding不一样的控制页面样式的方式,css binding须要依赖css文件中对应的样式表,借由增长或删除css class来改变样式,而style binding则是直接在相应的元素上添加或删除style来改变页面的样式。一个简单的例子以下:

js部分:

1 var myViewModel = {
2   redTextDecision: ko.observable("red")
3 };
4 
5 ko.applyBindings(myViewModel);

html部分:

1 <p data-bind="style: {color: redTextDecision}">This is red text.</p>

页面显示效果以下:

与css binding相似,咱们也能够一次性设定多个style,以下:

1 <p data-bind="style: {color: redTextDecision, align: alignDecision}">This is red text.</p>

若是绑定的viewModelProperty是一个observable,则每次observable改变的同时,UI会对对应的style进行更新;不然,UI只会设定一次style,以后再也不改变。

有些style是带有特殊符号的,好比"text-decoration",好比"font-size"。在这种状况下,直接在data-bind中填写style的原名是不妥的,咱们须将其变动为"textDecoration"和"fontSize",其余相似的情形以此类推。


attr binding用于绑定某些元素的attribute,好比说a元素的title、href,img元素的src等。一个简单的例子以下:

js部分:

1 var myViewModel = {
2   url: ko.observable("http://www.google.com"),
3   description: ko.observable("This is google's website"),
4   imgUrl: ko.observable("YukiNagato.JPG")
5 };
6 
7 ko.applyBindings(myViewModel);

html部分:

1 <a data-bind="attr {href: url, title: description}">Google's website</a>
2 <img style="weight: 100px; height: 100px" data-bind="attr {src: imgUrl}" />

页面显示效果以下:

若是绑定的viewModelProperty是一个observable,则每次observable改变时,UI均会更新相应的attribute;不然,UI只会设定一次attribute,以后再也不更新。

当attribute name中带有连字符号时,咱们只需在其外部添加一对引号便可。

相关文章
相关标签/搜索