Narutocc / knockout

0 stars 0 forks source link

knockout 指令1 #2

Open Narutocc opened 6 years ago

Narutocc commented 6 years ago
npm install knockout

页面引入 <script src="node_modules/knockout/build/output/knockout-latest.js"></script>

1. 数据声明

var myViewModel = {}

为保证里面使用的this指向不发生变化,最好写成函数的写法

function myViewModel(){var self = this;} 或者
var myViewModel = function(){var self = this;}

这样可以使共用逻辑的两个部分数据都有独立的空间

2. 定义数据

ko.applyBindings(myViewModel)

第二个参数必须是js对象,如果是使用jq获取的元素要转化成原生对象[0]

ko.applyBindings(viewModel, document.getElementById('body'));

3. 通过 data-bind 绑定数据

<div data-bind="text:name"></div>

data-bind里面有多个属性中间用逗号隔开

4. 数据双向绑定

ko.observable()
<input type="text" data-bind="value:name">

这种绑定只有input在失去焦点时视图层对应数据才会改变 解决方法: 第一:使用textInput代替value

<input type="text" data-bind="textInput:name">

这样在值的改变过程中视图层直接发生变化 第二:使用valueUpdate: 'afterkeydown'

<input type="text" data-bind="value:name,valueUpdate: 'afterkeydown'">

5. visible binding(元素只是隐藏)

<div data-bind="text:name,visible:bool"></div>

也可以直接三元表达式的运算

<div data-bind="text:name,visible:bool == 2 ? true:false"></div>

6. text binding

绑定的是文本就使用text属性

7. html binding

<div data-bind="html:html"></div>

8. css binding 对象写法

<style>
    .title{
        color:#ccc;
    }
</style>
<div data-bind="css:{title:bool}">test</div>

9. style binding 对象写法

<div data-bind="style:{'fontSize':'24px'}">test</div>

10. attr binding

可以代替css跟style语法

<div data-bind="attr:{title:name,class:'color',style:'margin-top:30px'}">test</div>

11. foreach

数据:数组

people:['小明','小红','小张']
<ul data-bind="foreach:people">
    <li data-bind="text:$data"></li>
</ul>

数据:数组里面对象

people2:[{
    name:'小明'
},{
    name:'小红'
},{
    name:'小张'
}]
<ul data-bind="foreach:people2">
    <li data-bind="text:name"></li>
</ul> 或者
<ul data-bind="foreach:people2">
    <li data-bind="text:$data.name"></li>
</ul>

两层循环 数据:数组嵌套数组

catalogs:ko.observable([
    {
        name:'水果',
        items:['apple','banana','orange']
    },{
        name:'蔬菜',
        items:['celery','corn','spinach']
    }
])
<ul data-bind="foreach:{data:catalogs,as:'catalog'}">
    <li>
        <span data-bind="text:catalog.name"></span>
        <ul data-bind="foreach:{data:items,as:'item'}">
            <li>
                <span data-bind="text:item"></span>
            </li>
        </ul>
    </li>
</ul>

另外一种写法:注释型

<!-- ko foreach: {data: test, as: '$row'}  -->
<!-- /ko -->

跟ember框架一样,as后面是自定义,此处后面数据用 $row. 代替

12. if && ifnot (元素会消失)

<div data-bind="if:true">if测试</div>
<div data-bind="ifnot:false">ifnot测试</div>

13. with

数据:对象嵌套

father:{
    data:'第一层',
    name:'father小明',
    children:{
        data:'第二层'
    }
}
<div data-bind="with:father">
    <p data-bind="text:data"></p>
    <p data-bind="text:$root.name"></p>
    <div data-bind="with:children">
        <p data-bind="text:data"></p>
        <p data-bind="text:$parent.name"></p>
    </div>
</div>

$root:返回根部数据 $parent:返回上一层父级数据

14. 事件

事件只有点击事件才可以在data-bind后面写click,其他事件都是通过event书写。

<div data-bind="click:clickFun,event:{mousedown:keyDownFun}">事件</div>

15. hasFocus

<input type="text" data-bind="hasFocus:true">

16. checked

checkArray:ko.observable(['zhangsan','lisi'])
<div>
    <input type="checkbox" name="people" value="zhangsan" data-bind="checked:checkArray">张三
    <input type="checkbox" name="people" value="lisi" data-bind="checked:checkArray">李四
    <input type="checkbox" name="people" value="wangwu" data-bind="checked:checkArray">王五
</div>

通过value值绑定,checkArray为true的只有zhangsan/lisi,所以张三李四默认勾选状态

改变数据,checkbox的选中状态改变跟selecte的option值改变 数据

checkArray:ko.observable(['zhangsan','lisi']),
changeData:function(){
    this.checkArray(['zhangsan','lisi','wangwu']);
    console.log(this.checkArray())
}
<div>
    <input type="checkbox" name="people" value="zhangsan" data-bind="checked:checkArray">张三
    <input type="checkbox" name="people" value="lisi" data-bind="checked:checkArray">李四
    <input type="checkbox" name="people" value="wangwu" data-bind="checked:checkArray">王五
</div>
<select data-bind="options: checkArray"></select>
<button data-bind="click:changeData">数据显示</button>

17. option

如果数据只是数组

checkArray:ko.observable(['zhangsan','lisi'])
<select data-bind="options: checkArray"></select>

如果数据是数组嵌套对象

people:[{name:'小明'},{name:'小红'},{name:'小张'}],
selectedName:ko.observable(),
showSelectedName:function(){
    console.log(this.selectedName().name)
},
<select data-bind="options: people2,optionsText: 'name', value: selectedName"></select>
<button data-bind="click:showSelectedName">显示名称</button>

使用了ko.observable()定义的数据,就表示一个方法,所以要打印出来就必须加括号,

this.selectedName()

通过value值绑定select框跟button之间的数据联系

Narutocc commented 6 years ago

1. dependentObservable

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    Name:<input type="text" data-bind="value:name,valueUpdate:'afterkeydown'" >
    <input type="checkbox" data-bind="checked:nameVisible">
    <p>
        Hello,<span data-bind="text:name,visible:nameVisible"></span>
        <br/>
        <span data-bind="text:displayName"></span>
    </p>
    <button data-bind="click:changeName">Change Name</button>
</body>
<script src="node_modules/knockout/build/output/knockout-latest.js"></script>
<script>
    var viewModel = {
        name:ko.observable('bob'),
        changeName:function(){
            this.name('kev')
        },
        nameVisible:ko.observable(true),    
    }
    viewModel.displayName = ko.dependentObservable(function(){
        return this.name() + ' is ' + (!this.nameVisible() ? " not ":"") + "visible.";
    },viewModel)

    ko.applyBindings(viewModel)
</script>
</html>