前端二三事

knockoutjs初体验

2017-07-09  本文已影响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());

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

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

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

防止事件冒泡

    <button data-bind="event: { mouseover: myButtonHandler },mouseoverBubble: false">
        Click me
</button>
上一篇 下一篇

猜你喜欢

热点阅读