数组元素的新增/移除事件

前两篇博客已经很清楚的知道knockout.js通过observableArray()数组元素增减,可以实时的反映在UI上。 当然我们想在数组增加或移除元素时加上自定义逻辑就好比一个触发器的感觉,可以吗?

foreach提供了afterAdd及beforeRemove两个额外的事件,允许在数组新增、移除元素时执行特定逻辑。 在此继续沿用先前的用户列表呈现范例,加上两个效果:

  • 新增数据时,将最新加入的数据和表格进行着色修饰

  • 删除数据时,加上数据淡出特效

而在ViewModel里我们加上两个函数:

//添加对象后才触发,第一次forach并不会触发
            self.afterAddEvent = function (element, index, data) {
                //通过nodeType过滤,只处理Element Node
                if (element.nodeType==1)  
                {
                    $(".new").removeClass("new");
                    $(element).addClass("new");
                }
            };
            //注意: beforeRemove事件后,要自已移除被刪除元素
            self.beforeRemoveEvent = function (element, index, data) {
                if (element.nodeType == 1) {
                    $(element)
                    .css("background-color", "#ff6a00")
                    .animate({ opacity: 0.2 },1000, function () {
                        $(this).remove();
                    })

                }
            };

afterAdd及beforeRemove函数会固定收到三个参数,element、index及data,其中 element 为模板容器中的各元素,即:

 <tr>
                    <td><span data-bind="text: id"></span></td>
                    <td><span data-bind="text: name"></span></td>
                    <td><span data-bind="text: score"></span></td>
                    <td><a href='#' data-bind="click: $root.removeUser">Remove</a></td>
                </tr>

实际运作时afterAdd/beforeRemove会收到不同的element被呼叫三次,原因是除了<tr>之 外,<tbody>到<tr>之间的空白、</tr>到</tbody>间的空白也各算一个 Element,(FF和chrome是忽略这个空格的)其 nodeType 为3即TEXT_NODE, 代表TEXT_NODE。 因此三次传入的element分别为TEXT_NODE、ELEMENT_NODE、TEXT_NODE,而第二次传入的ELEMENT_NODE 是<tr>...</tr>间的内容,才是我们需要处理的对象,故加入if (elems.nodeType == 1)的判断。

要注意,一旦调用了了beforeRemove,konckout.js就不再自动帮你移除该笔数据在网页对应的元素,必须自行处理,但这也提供开发人员绝对的控制权,可自由安排HTML元素要怎么从网页上退出。

完整代码如下:

<!DOCTYPE html>
<html>
    
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>
            Index2
        </title>
        <style>
            table { width: 385px } td,th { border: 1px solid #0094ff; text-align:
            center; } .new { color: #0094ff; background-color:#b6ff00}
        </style>
        <script src="~/Scripts/jquery-2.0.3.js">
        </script>
        <script src="~/Scripts/knockout-2.3.0.js">
        </script>
        <script type="text/javascript">
            //定义user数据对象
            function UserViewModel(id, name, score) {
                var self = this;
                self.id = id;
                self.name = ko.observable(name);
                self.score = ko.observable(score);
            }
            //定义ViewModel
            function ViewModel() {
                var self = this;
                self.users = ko.observableArray(); //添加动态监视数组对象
                self.removeUser = function(user) {
                    self.users.remove(user);
                }
                self.totalscore = ko.computed(function() {
                    var total = 0;
                    $.each(self.users(),
                    function(i, u) {
                        total += u.score();
                    })
                    return total;
                });
                //添加对象后才触发,第一次forach并不会触发
                self.afterAddEvent = function(element, index, data) {
                    //通过nodeType过滤,只处理Element Node
                    if (element.nodeType == 1) {
                        $(".new").removeClass("new");
                        $(element).addClass("new");
                    }
                };
                //注意: beforeRemove事件后,要自已移除被刪除元素
                self.beforeRemoveEvent = function(element, index, data) {
                    if (element.nodeType == 1) {
                        $(element).css("background-color", "#ff6a00").animate({
                            opacity: 0.2
                        },
                        600,
                        function() {
                            $(this).remove();
                        })

                    }
                };
            };
            $(function() {
                var vm = new ViewModel();
                //预先添加一些数据
                vm.users.push(new UserViewModel("d1", "rohelm", 121));
                vm.users.push(new UserViewModel("d2", "halower", 125));
                $("#btnAddUser").click(function() {
                    vm.users.push(new UserViewModel(
                    $("#u_id").val(), $("#u_name").val(), parseInt($("#u_score").val())));
                });
                $("#btnUpdateScore").click(function() {
                    vm.users()[vm.users().length - 1].score(125).name("HelloWorld!");
                });
                ko.applyBindings(vm);
            });
        </script>
    </head>
    
    <body>
        <section style="margin:250px">
            <section>
                ID
                <input type="text" id="u_id" style="width:30px">
                Name
                <input type="text" id="u_name" style="width:30px">
                Score
                <input type="text" id="u_score" style="width:30px">
                <br/>
                <input value="Add" id="btnAddUser" type="button" style="width:200px; background-color:#ff6a00;"
                />
                <br/><span data-bind="text: users().length">
                </span>--------------合计
                <span data-bind="text: totalscore">
                </span></section>
            <section>
                <table>
                    <thead>
                        <tr>
                            <th>
                                ID
                            </th>
                            <th>
                                Name
                            </th>
                            <th>
                                Score
                            </th>
                            <th>
                                Option
                            </th>
                        </tr>
                    </thead>
                    <tbody data-bind="foreach: { data: users, afterAdd: afterAddEvent, beforeRemove: beforeRemoveEvent}">
                        <tr>
                            <td>
                                <span data-bind="text: id">
                                </span>
                            </td>
                            <td>
                                <span data-bind="text: name">
                                </span>
                            </td>
                            <td>
                                <span data-bind="text: score">
                                </span>
                            </td>
                            <td>
                                <a href='#' data-bind="click: $root.removeUser">
                                    Remove
                                </a>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <input value="Update测试" id="btnUpdateScore" type="button" style="width:200px; background-color:#ff6a00;"
                />
                <br/>
            </section>
        </section>
    </body>

</html>

转载于:https://www.cnblogs.com/wuxl360/p/5761183.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值