knockoutjs初体验

作者: 夏不吓 | 来源:发表于2017-07-09 11:47 被阅读222次

据说knockoutjs差不多被拍死了,在众多mvvm框架当中,用于复杂的项目干不过angular,简单点的又有vue、react,再简单的话就都不需要用这些东西了,但是公司一个项目用到这个东西,貌似这个东西再配合jQuery还是挺好用的,还有兼容性好,个子小,简洁等优点
中文文档传送门
------------------------------------------------分割线---------------------------------------
首先knockoutjs是基于jQuery的,也就是说引入这玩意之前得先引入jQuery

对于MVVM的理解
model: ko通过ajax向服务器请求的数据模型
viewModel:个人认为就是操作页面的js代码
view:就是可见的页面(是否就是html和css组成的页面?)
(个人对于mvc、mvvm这些还是比较模糊的)

创建数据模型(View Models )和监控属性(Observables)

使用KO创建一个View Model,仅仅只需要声明一个JavaScript对象,也就是在script标签内创建一个对象

var myViewModel = {personName: 'Bob',personAge: 123};

当然了,对象的名字是随你喜欢

<span data-bind="text: personName"></span>//这是绑定到标签上,使用的都是data-bind

最后是激活

ko.applyBindings(myViewModel )

这样整个过程便完成了,当然除了激活意外,对象的内容和绑定标签的属性是需要根据需要而改变的
ko.applyBindings(obj,[node] )接收两个参数,第一个参数是必须的,是创建的对象,第二个是可省的,你可以使用第二个参数来设置要使用data-bind属性的HTML元素或容器,同一个容器内只能进行一次激活

//容器1
<div class="box">
    <input type="text" data-bind="value:text">
    <span data-bind="text: value"></span>
</div>
//容器2
<div class="box2">
    <input type="text" data-bind="value:text1">
</div>


<script src="knockout.js"></script>
<script>
    var viewPoint = {
        text: ko.observable("abc"),
        value: ko.observable("123"),  
    }
    
    ko.applyBindings(viewPoint,document.querySelector(".box"))//指定容器1范围


    var viewPoint1 = {
        text1:ko.observable("321")
    }

    ko.applyBindings(viewPoint1,document.querySelector(".box2"))//容器2激活
</script>

若是这样,则报错

<div class="box">
    <input type="text" data-bind="value:text">
    <span data-bind="text: value"></span>
</div>
<script src="knockout.js"></script>
<script>
    var viewPoint = {
        text: ko.observable("abc")
    }
    ko.applyBindings(viewPoint)

    var viewPoint1 = {
        value:ko.observable("321")
    }

    ko.applyBindings(viewPoint1)
    //报错

Observables

这玩意是启动监控,监控data-bind设置的内容,如

<input data-bind="value: personName">
var myViewModel = {personName: ko.observable()};//当input里面的值改变的时候,同时会将值赋给personName,然后就能在myViewModel 对象里面查看,当然也可以通过ko.observable()去设定输入框的值,比如

{personName: ko.observable(123)},输入框里面的值就会是123,貌似使用value的话,ko.observable()传入的参数只能是常量,如果是变量,即使在上下文当中该变量有所改变,输入框的值也不会变,如果要动态的双向绑定的话,是否是需要其他的属性??

要注意的是ko.observable监控的对象都是方法。也就是说你想拿输入框的值,你需要这样var data = myViewModel .personName(),像执行行数一样
饥人是双向绑定,那么就是随时可以通过js随时去改变这个值,比如这样

<div data-bind="text: shouldShowMessage"> </div>
<button class="btn">点我</button>
/*--------------------------------------------*/
var btn = document.querySelector(".btn");
var viewModel = {
    shouldShowMessage: ko.observable(123)
};
 
btn.addEventListener("click",function(){
    console.log(1)
    viewModel.shouldShowMessage(321); //注意重新给值的格式
})
ko.applyBindings(viewModel)

监控属性数组

var myObservableArray = ko.observableArray([
{name: "Bungle", type: "Bear" }, 
{name: "George", type: "Hippo" },
{name: "Zippy", type: "Unknown" }]);  //括号里面的参数是一个数组

上面是用ko.observable()取监控value字符串,那如果是数组的话,就得用ko.observableArray()去监控

<select width:100px data-bind="options: selectOptions, optionsText: 'name', optionsValue: 'type' "> </select>

var arr = [  
            {name: "Bungle", type: "Bear" }, 
            {name: "George", type: "Hippo" },
            {name: "Zippy", type: "Unknown" }
        ]

 var form = {
   selectOptions: ko.observableArray(arr)
 }
 //  function Form(){
 //      this.selectOptions = ko.observableArray(arr)
 //  } //也可以是函数
// ko.applyBindings(new Form())

  ko.applyBindings(form)

貌似只有下拉列表能这么玩

Knockoutjs数组常用的方法如下:

(1)、myObservableArray.push('Some new value'):增加一个新的元素

(2)、myObservableArray.pop():删除一个元素,并返回其值

(3)、myObservableArray.unshift('Some new value'):在数组的开始处增加一个新的元素

(4)、myObservableArray.shift():删除数组的第一个元素,并返回其值

(5)、myObservableArray.reverse():反转数组的顺序

(6)、myObservableArray.sort():数组排序。排序规则可以由用户自己定义也可以使用默认,默认情况下按照字母顺序或者数字的顺序进行排序。自己定义排序规则时需要接收数组 中的两个元素,并且需要返回一个数值,当此值小于0时表示第一个元素较小,当此值大于0时,表示第二个元素较小,当等于0时表示两个元素相等。这基本和js一样
(7)、myObservableArray.splice():数组截取

observerbale.remove(item),移除所有符合item的对象,并把这些对象作为一个数组返回

myObservableArray.remove(function(item) { return item.age < 18 })
//移除myObservableArray数组内所有年龄属性小于18的对象,并返回这些对象组成的新数组

计算属性

ko.computed()

<span name="" id="" width="100" data-bind="text:fullName"></span>
<button class="btn">点我</button>
var aa = 1,bb = 2;
var form = {
    fullName:ko.computed(function(){return aa+bb})  //显示3
}
ko.applyBindings(form)

也可以这样玩,通过页面的输入而改变页面的其他值

function MyViewModel() {
    this.firstName = ko.observable('Planet');
    this.lastName = ko.observable('Earth');
    this.fullName = ko.computed({
        read: function () { }, //一般用于显示自己的值
        write: function (value) {
            var self = this
            var btn = document.querySelector(".btn")
            btn.addEventListener("click",function(){
                var lastSpacePos = value.lastIndexOf(" ");
                // Ignore values with no space character
                self.firstName(value);
                // Update "firstName"
                self.lastName(value+"我");
                // Update "lastName"
            })
        
        }, owner: this //把this指向的环境传进来
    });
}
ko.applyBindings(new MyViewModel());

但是,不能这样玩(通过用就是改变变量来改变原以定好的页面的值)
比如这样

        btn.addEventListener("click",function(){

            value = "hello word" // 和上面的代码的区别就是重新赋值给value
            var lastSpacePos = value.lastIndexOf(" ");
            // Ignore values with no space character
            self.firstName(value);
            // Update "firstName"
            self.lastName(value+"我");
            // Update "lastName"
        })
        
    }, owner: this //把this指向的环境传进来

还可以做表单验证,以下是只能输入数字,若不是,则会提示

<p>Enter a numeric value:<input data-bind="value: attemptedValue"/></p>
<div data-bind="visible: !lastInputWasValid()">That's not a number!</div>

function MyViewModel() {
    this.acceptedNumericValue = ko.observable(123);
    this.lastInputWasValid = ko.observable(true);
    this.attemptedValue = ko.computed({
    read: this.acceptedNumericValue, //对应this.acceptedNumericValue,write部分会进行验证,只输出数字部分,显示在attemptedValue
    write: function (value) {
        console.log(this.acceptedNumericValue())//数值部分
        if (isNaN(value))
            this.lastInputWasValid(false);
        else {
            this.lastInputWasValid(true);
            this.acceptedNumericValue(value);
            // Write to underlying storage 
        }
    }, owner: this
});
}

ko.applyBindings(new MyViewModel());

----------------------------------------------我是分割线----------------------------------------------

  • visible绑定
    无非就是true可见,false不可见,不仅是通过传入布尔值去改变,还可以通过函数表达式(无非就是执行该表达式返回的结果是true还是false)

    <div data-bind="visible: shouldShowMessage"> You will see this message only when "shouldShowMessage" holds a true value.
    

    </div>

    <div data-bind="visible: myValues().length >0"> You will see this message only when 'myValues' has at least one     member.
    

</div>
可以通过js随时改变这个布尔值

  var viewModel = {
      shouldShowMessage:ko.observable(true)
  }
  $(node).on("click",function(){
    viewModel.shouldShowMessage(false)
  })
  ko.applyBindings(viewModel)
  • Text绑定

    <span data-bind="text:userName"></span>
    
    var form = {
        user: ko.observable("123")
    }
    form.userName = ko.computed(function(){
      return this.user.length>3?"123":"321"
    },form) //需要传进this
    
  • html绑定
    当代码中有html标签的时候,会进行编译,而如果用text则不编译,标签以文本的方式显示
    <div data-bind="html: details"></div>
    var viewModel = {
    details: ko.observable() // Initially blank
    };
    viewModel.details("<em>For further details</em>")//斜体For further details
    ko.applyBindings(viewModel)

  • CSS类名绑定
    用true和false决定是否使用该class,可以用表达式,也可以直接是true和false

    <div data-bind="css: { profitWarning: currentProfit() < 0,majorHighlight: isSevere }">
    <div data-bind="css: { 'my-class': someValue }">...</div> //注意变量名的格式,像这般,要加引号,一般加上引号就没有错
    
  • Style属性绑定
    这和class绑定类似

    <div data-bind="style: { color: currentProfit() < 0 ? 'red' : 'black' }">     Profit Information
    

    </div>
    注意有横杠的一些样式的定义
    错误:{ font-weight: someValue }; 正确:{ fontWeight: someValue }

  • attr属性绑定
    类似于href、title等属性的绑定(可以动态)

    <a data-bind="attr: { href: url, title: details }">
        Report
    </a>
    <button class="btn">点我</button>
        var viewModel = {
      url: ko.observable("#"),
      details: ko.observable("Report including final year-end statistics")
    }
    
    ko.applyBindings(viewModel)
    
    var btn = document.querySelector(".btn")
    btn.addEventListener("click",function(){
      viewModel.url("https://baidu.com")
    })
    
  • foreach绑定
    就是遍历数组,通常用于列表,详细参考点我,$parent、$index、$data、as(命名)

       <table> 
       <thead> 
           <tr><th>First name</th><th>Last name</th></tr> 
       </thead> 
       <tbody data-bind="foreach: people"> 
           <tr> 
               <td data-bind="text: firstName"></td> 
               <td data-bind="text: lastName"></td> 
           </tr> 
       </tbody> 
       </table> 
    
       ko.applyBindings({
       people: [
           { firstName: 'Bert', lastName: 'Bertington' },
           { firstName: 'Charles', lastName: 'Charlesforth' },
           { firstName: 'Denise', lastName: 'Dentiste' }
       ]
     });
    
  • if绑定
    决定显示与否,下过和visible类似,与visible不同的是,if binding是真正的控制Html标签是否出现在DOM中,如果绑定的值为false,则Html标签不会出现在页面中,回频繁地操作dom

  • with绑定
    可以使用with binding来重新定义一个上下文绑定,按照我的理解是这样的

      <p data-bind="with: coords"> //coords是一个对象
          Latitude:
      <span data-bind="text: latitude">  //latitude和longitude是对象里面的属性或者方法,
      //一般访问的话需要是coords.latitude,而现在只需要用latitude就行,
      //这就是父元素上用了width指定了上下文的功劳
      </span>
          , Longitude:
      <span data-bind="text: longitude">
      </span>
      </p>
    
      ko.applyBindings({
      coords: {
          latitude: 51.5001524,
          longitude: -0.1262362
      }
    });
    
  • click绑定
    点击事件,默认情况下,Knockout会阻止冒泡,防止默认的事件继续执行
    也可以这样去阻止冒泡
    <button data-bind="click: myButtonHandler, clickBubble: false">
    Click me
    </button>

  • event绑定
    keypress,mouseover和mouseout,change

      <div data-bind="event: { mouseover: myFunction }">
          Mouse over me
      </div>
    
      var viewModel = {
          myFunction: function(event) {
                if (event.shiftKey){doSomething}
          }
    

防止事件冒泡

    <button data-bind="event: { mouseover: myButtonHandler },mouseoverBubble: false">
        Click me
</button>
  • submit绑定

  • value绑定
    注意valueUpdate参数,如果使用valueUpdate参数,那就是意味着KO将使用自定义的事件而不是默认的离开焦点事件
    <input data-bind="value: someValue, valueUpdate: 'afterkeydown'" />

相关文章

  • knockoutjs初体验

    据说knockoutjs差不多被拍死了,在众多mvvm框架当中,用于复杂的项目干不过angular,简单点的又有v...

  • KnockoutJS学习与应用

    KnockoutJS学习与应用 KnockoutJS初认识 KnockoutJs是针对Web开发的MVVM框架(M...

  • 【100个前端小项目-2】KnockoutJS 实现To-do

    最近接手的任务用的是KnockoutJS + TypeScript,所以第二个项目就采用KnockoutJS做一个...

  • knockoutjs

    1. if 绑定 1) 目的 if绑定扮演着和visible绑定类似的角色。不同之处在于,visible绑定中,标...

  • ko网址

    http://www.aizhengli.com/knockoutjs/57/knockout-applybind...

  • knockoutJS用法

    ko中的 data-bind属性 text 和 inputTexttext,顾名思义就是文本的意思,这个绑定属性一...

  • knockoutJs学习资料

    1、Knockout中文开发指南2、深入浅出knockoutJs3、绑定上下文4、事件传递参数的方法

  • yii初体验(7-15)

    yii初体验(7)视图 yii初体验(8)模块 yii初体验(9) 小部件widgets yii初体验(10) 前...

  • knockout js 事件默认加载和数组更新方法

    1、前端使用knockoutJs框架,在foreach遍历中添加弹出框事件,如何对foreach出来的数据进行修改...

  • magento2教程之knockout-Observables

    本文转载自Magento中文网(magento360.cn) magento2中结算页面使用了knockoutjs...

网友评论

  • lw5116:ko不基于jq吧 你貌似搞错了
    夏不吓:谢谢指出,不基于jq,应该算是相辅相成,两者交叉用更配:grin:

本文标题:knockoutjs初体验

本文链接:https://www.haomeiwen.com/subject/eoxxcxtx.html