• (二)Knockout 文本与外观绑定


    Visible

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

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

        <div data-bind="visible: shouldShowMessage">
          You will see this message only when "shouldShowMessage" holds a true
          value.
    	</div>
    	
    	<script>
    		var viewModel = {
    		  shouldShowMessage: ko.observable(true) // Message initially visible
    		};
    		viewModel.shouldShowMessage(false); //隐藏元素
    		//viewModel.shouldShowMessage(true);  //显示元素
    		ko.applyBindings(viewModel);
    	  </script>
    

    text

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

       <p>This is my text: <span data-bind="text: myText"></span></p>
    
        <script>
          var myViewModel = {
            myText: ko.observable()
          };
    
          ko.applyBindings(myViewModel);
    
          myViewModel.myText("Hello world!");
          ko.applyBindings(viewModel);
        </script>
    

    输出结果:

    This is my text: Hello world!

    备注 1 : 使用函数和值表达式

     <p>This is my text: <span data-bind="text: myComputed"></span></p>
        
        <script type="text/javascript">
          var viewModel = {
            myText: ko.observable(60),
          };
    
          viewModel.myComputed = ko.pureComputed(function () {
            return this.myText() > 50 ? "Big" : "Small";
          }, viewModel);
    
          ko.applyBindings(viewModel);
    
        </script>
    

    输出结果:

    This is my text: Big

    备注2:关于HTML编码

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

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

    输出结果:

    This is my text: <i>Hello world!</i>

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

    备注3:无容器

    在某些时候,我们需要在不指定元素的情况下直接插入text,此时我们可以使用无容器的语法来定义一个text binding。例如在option element中是不允许包含其他元素的,如果我们如下定义data-bind

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

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

    <select data-bind="foreach: myItems">
        <option>Item <!--ko text: name--><!--/ko--></option>
    </select>
    

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

    完整的案例:

    <select data-bind="foreach: myItems">
      <option>Item <span data-bind="text: name"></span></option>
    </select>
    
    <select data-bind="foreach: myItems">
        <option>Item <!--ko text: name--><!--/ko--></option>
    </select>
    
    <script type="text/javascript">
        var vm = {
            myItems: [
                { name: 'Item 1', id: 1},
                { name: 'Item 3', id: 3},
                { name: 'Item 4', id: 4}
            ]
        };
        ko.applyBindings(vm);
    </script>
    

    html

    Html binding其实与text binding类似,只不过它的参数一般是带有html标签的,这样就可以自定义想要绑定的html元素。

    下面是个很简单的例子:

    var myViewModel = {
      myHtml: ko.observable(),
    }
    
    ko.applyBindings(myViewModel);
    
    myViewModel.myHtml("<a href='http://www.google.com'>Google</a>");
    

    html

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

    class与css

    class绑定

          <div data-bind="class: profitStatus">
              Profit Information
           </div>
    
        <script type="text/javascript">
          var viewModel = {
              currentProfit: ko.observable(150000)  //<div data-bind="class: profitStatus" class="profitPositive"> 
          };
       
          // Evalutes to a positive value, so initially we apply the "profitPositive" class
          viewModel.profitStatus = ko.pureComputed(function() {
              return this.currentProfit() < 0 ? "profitWarning" : "profitPositive";
          }, viewModel);
       
          // Causes the "profitPositive" class to be removed and "profitWarning" class to be added
          viewModel.currentProfit(-50);  //<div data-bind="class: profitStatus" class="profitWarning"> 
          ko.applyBindings(viewModel);
        </script>
    

    改变的是class的值。

    静态类

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

        <style>
          .redText {
           color: red;
          }
        </style>
      </head>
      <body>
        <p data-bind="css: { redText: myTest() > 0 }">Test for css binding</p>
    
        <script type="text/javascript">
          var myViewModel = {
            myTest: ko.observable()
          };
          myViewModel.myTest(20);
          console.info(myViewModel.myTest());
          ko.applyBindings(myViewModel);
        </script>
    

    动态类

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

    <style>
         .redText {
           color: red;
         }
    
         .blueText {
           color: blue;
         }
       </style>
    
       <p id="redText" data-bind="css: myComputed">This is red text.</p>
       <p id="blueText" data-bind="css: myComputed">This is blue text.</p>
    
       <script type="text/javascript">
         var myViewModel1 = {
           myTest: ko.observable(),
           myComputed: ko.pureComputed(function() {
             return myViewModel1.myTest() > 0 ? "redText" : "blueText";
           })
         };
    
         var myViewModel2 = {
           myTest: ko.observable(),
           myComputed: ko.pureComputed(function() {
             return myViewModel2.myTest() > 0 ? "redText" : "blueText";
           })
         };
    
         ko.applyBindings(myViewModel1, document.getElementById("redText"));
         ko.applyBindings(myViewModel2, document.getElementById("blueText"));
    
         myViewModel1.myTest(20);
         myViewModel2.myTest(-20);
       </script>
    

    静态类绑定多个class

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

        <style>
          .redText {
            color: red;
          }
    
          .textDecoration {
            text-decoration: underline;
          }
        </style>
    
        <p
          data-bind="css: {redText: redTextDecision, textDecoration: textDecorationDecision}"
        >
          This is red text, and its text-decoration is underline.
        </p>
    
        <script type="text/javascript">
          var myViewModel = {
            redTextDecision: ko.observable(),
            textDecorationDecision: ko.observable()
          };
    
          ko.applyBindings(myViewModel);
    
          myViewModel.redTextDecision(true);
          myViewModel.textDecorationDecision(true);
        </script>
    

    在上例中,我们是使用两个view model的property来决定两个不同的css class,KO也允许我们使用一个view model property来决定多个css class,可将上例的html部分改成如下形式:

    <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,之后不再更新。

    动态类绑定多个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以空格分开并统一以字符串的方式返回即可。一个简单的例子如下:

    <style>
          .redText {
            color: red;
          }
    
          .textDecoration {
            text-decoration: underline;
          }
        </style>
    
        <p data-bind="css: textDecorationDecision">
          This is red text, and its text-decoration is underline.
        </p>
    
        <script type="text/javascript">
          var myViewModel = {
            textDecorationDecision: ko.observable("textDecoration redText")
          };
    
          ko.applyBindings(myViewModel);
        </script>
    

    备注: 应用名称不是合法的 javascript 变量名的 css 类

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

    如果你想套用 CSS 类my-class你 ,不能这样写 :

    <div data-bind="css: { my-class: someValue }">...</div>
    

    因为我的类在这一点上不是一个合法的标识符名称。解决方案很简单: 只需用引号包装标识符名称, 使其成为字符串文本, 这在 javascript 对象文本中是合法的。例如,

    <div data-bind="css: { 'my-class': someValue }">...</div>
    

    style

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

    <p data-bind="style: {color: redTextDecision}">This is red text.</p>
    
        <script type="text/javascript">
          var myViewModel = {
            redTextDecision: ko.observable("red")
          };
    
          ko.applyBindings(myViewModel);
        </script>
    

    与css binding类似,我们也可以一次性设定多个style,如下:

    <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",其他类似的情形以此类推。

    Don’t write { font-weight: someValue }; do write { fontWeight: someValue }
    Don’t write { text-decoration: someValue }; do write { textDecoration: someValue }

    attr

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

    <a data-bind="attr :{ href: url, title: description}">Google's website</a>
        <img style=" 100px; height: 100px" data-bind="attr: {src: imgUrl}"  />
        <script type="text/javascript">
          var myViewModel = {
            url: ko.observable("http://www.google.com"),
            description: ko.observable("This is google's website"),
            imgUrl: ko.observable("http://i1.sinaimg.cn/dy/deco/2013/0329/logo/LOGO_1x.png")
          };
    
          ko.applyBindings(myViewModel);
        </script>
    

    如果绑定的viewModelProperty是一个observable,则每次observable改变时,UI均会更新相应的attribute;否则,UI只会设定一次attribute,之后不再更新。

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

    参考:

    CharlieYuki,KnockoutJs学习笔记(五)

  • 相关阅读:
    二分查找改遍
    条件运算符?:
    k倍区间
    分巧克力
    mm
    素数
    递归return
    确定一个域名使用的邮箱服务商
    mysql 存储过程一实例
    使用vmware 共享 windows下的文件夹 到 centos
  • 原文地址:https://www.cnblogs.com/tangge/p/10301433.html
Copyright © 2020-2023  润新知