knockoutjs总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_30682027/article/details/80319386

knockoutjs总结

之前写的两篇博客
knockoutJs在项目中的使用
knockout.js做table列表

参考
KnockOut : Introduction

特殊变量

$root

$root指的是ko所绑定的DOM,可以解决类似于作用域的问题,一般来说withforeach等,在对应的dom标签区间中的属性是对应于with绑定的对象以及foreach循环中每一个对象中的变量,如果想在该标签区间内使用ViewModel中的其它属性,则会报错说找不到或者未定义之类的,那么就需要使用$root来指定作用域为ViewModel.
如下代码

 <div class="input_list clearfix" data-bind="with:cpafInfoCondition">
     <div class="input_box clearfix">
         <div class="tabs-input clearfix fl">
             <p class="fl">行政区划</p>
             <ul class="select fl">
                 <li class="selected">-请选择-</li>
                 <li class="option">
                     <ul data-bind="html:$root.divisionUl"></ul>
                 </li>
             </ul>
         </div>
         .....

        self.cpafInfoCondition = ko.observable({currentPage:0,
            pageSize : 20,
            divisionProvince : '',
            cpafCno : '',
            cpafName : '',
            cpafStatus : '',
            cpaNumBegin : '',
            cpaNumEnd : '',
            orgForm : ''
        });
        ...
        //区划
        self.divisionUl = (function () {

$parent

$parent 是指当前DOM元素直接的外部父类(只有一层);

with绑定

参考:knockoutjs六 with 绑定
在我看来,with是一个作用域或者上下文的限制。假设对象obj={key:val},那么在with:obj下可以直接使用key,而不需要使用obj.key
with还有个作用,当with的条件是null或者是undefined,那么下面的子元素就不会加载,如果不空就加载,这样就避免了一些错误,不会当obj是null或者是undefined的时候还调用obj.key发生报错。

虚拟元素

参考:Creating custom bindings that support virtual elements
如下


<!-- ko if:cpafNameNoData -->
<tr class="no-data">
    <td colspan="4">暂无符合条件的数据</td>
</tr>
<!-- /ko -->
<!-- ko foreach : cpafNameList -->
<tr class="midlist-top">
    <td class="zczsbh" data-bind="text:divisionProvince"></td>
    <td class="zsxm" data-bind="text:cpafNo"></td>
    <td class="zszt" data-bind="text:cpafName"></td>
    <td class="swsmc" data-bind="text:cpafAbbr"></td>
</tr>
<!-- /ko -->

使用<!-- ko --><!-- /ko -->做一个虚拟节点,注意写法,在–和尖括号之间是没有空格的,个人觉得有点像vue中使用Template元素渲染的意思

事件绑定及参数传递

以click为例

  • 简单绑定
data-bind="click:funcName"
  • 如果有多个事件需要一起绑定
data-bind="event:{click:clickFuncName,change:changeFuncName}"
  • 如果需要传递参数
    默认的,knockout会传递两个参数出来。
    第一个参数是自己定义的ViewModel,第二个则是触发的event
    • 第一种方式
//这里的$data不可以省略
//这种方式,默认参数在最后.
data-bind="click:clickFuncName($data,'param1','param2')"
- 第二种方式
<button data-bind="click: function(data, event) { myFunction('param1', 'param2', data, event) }">
    Click me
</button>

问题总结

在layer中使用knock的奇怪问题

需求:当没有数据的时候显示”没有查询到符合条件的数据”,否则显示数据
问题描述:当数据从无到有或者从有到无时,tbody再也无法显示任何内容了
问题代码如下

//layer弹出表格
layer.open({
                title: '处罚信息',
                type: 1,
                content: $(cpafPunish),
                area: ['1080px', '460px'],
                success: function () {
                    cpafPunishViewModel = new CpafPunishViewModel();
                        ko.cleanNode(cpafPunish);
                        ko.applyBindings(cpafPunishViewModel, cpafPunish);
                    cpafPunishViewModel.init(data.CPAF_NO);
                },
                end: function () {
                    $(cpafPunish).hide();
                }
            });

......
//表格的viewmodel
function CpafPunishViewModel() {
        var self = this;
        self.cpafPunishNoData = ko.observable(true);
        self.cpafPunishList = ko.observableArray([]);
        //查询列表
        self.init = function (cpafNo) {
            self.cpafPunishList([]);
            $.postAjax(contentPath + "/searchBfLogin/searchCpafPunish", {cpafNo: cpafNo}, function (list) {
                self.cpafPunishNoData(list.length < 1);
                self.cpafPunishList(list);
            }, true);
        }
    }

下表是表格

<div id="cpafPunish" style="display: none;height:50px;margin:0 auto;" class="layer_notice">
    <div class="table-wrap">
        <table class="conList">
            <thead>
            <th width="80">行政区划</th>
            <th width="150">事务所名称</th>
            <th width="120">执业证书编号</th>
            <th width="120">处罚类型</th>
            <th width="120">做出处罚时间</th>
            </thead>
            <tbody class="midlist-body">
            <!-- ko if: cpafPunishNoData -->
            <tr class="no-data">
                <td colspan="5">暂无符合条件的数据</td>
            </tr>
            <!-- /ko -->
            <!-- ko foreach: cpafPunishList -->
            <tr class="midlist-top">
                <td data-bind="text:DIVISION_NAME"></td>
                <td data-bind="text:CPAF_NAME"></td>
                <td data-bind="text:CPAF_CNO"></td>
                <td data-bind="text:PUNISH_TYPE"></td>
                <td data-bind="text:FILE_DATE"></td>
            </tr>
            <!-- /ko -->
            </tbody>
        </table>
    </div>
</div>

解决问题的代码如下,即只new和绑定都只一次

self.viewPunish = function (data) {
            var cpafPunish = document.getElementById('cpafPunish');
            layer.open({
                title: '处罚信息',
                type: 1,
                content: $(cpafPunish),
                area: ['1080px', '460px'],
                success: function () {
                    if (cpafPunishViewModel === undefined) {
                        cpafPunishViewModel = new CpafPunishViewModel();
                        ko.cleanNode(cpafPunish);
                        ko.applyBindings(cpafPunishViewModel, cpafPunish);
                    }
                    cpafPunishViewModel.init(data.CPAF_NO);
                },
                end: function () {
                    $(cpafPunish).hide();
                }
            });
        };

暂时还找不到合理的解释。

Knockout checkbox click 冲突

给checkbox绑定click,发现checkbox无法选中。网上查阅资料发现knockout在处理checkbox的checked和click时,需要一点小技巧
使用knockout同时绑定checked和click时,checkbox点击不勾选,在绑定的click事件中一定要返回true;

        self.checkAll = function () {
            var target = event.srcElement || event.target;
            $('.sfq-all-check').prop('checked', $(target).prop('checked'));
            return true;
        };

猜你喜欢

转载自blog.csdn.net/qq_30682027/article/details/80319386