关闭

knockout.js实例一~联系人管理器

标签: knockoutjs
389人阅读 评论(0) 收藏 举报
分类:

knockout.js实例一~联系人管理器

本次实例是基于knockout.js来完成对联系人的管理(增,删),不多说直接先上代码:

ViewModel

//[1]
var initialData = [
    { firstName: "Danny", lastName: "LaRusso", phones: [
        { type: "Mobile", number: "(555) 121-2121" },
        { type: "Home", number: "(555) 123-4567"}]
    },
    { firstName: "Sensei", lastName: "Miyagi", phones: [
        { type: "Mobile", number: "(555) 444-2222" },
        { type: "Home", number: "(555) 999-1212"}]
    }
];


function contactsModel(){
    var self = this;

    //[2]   
    self.contacts = ko.observableArray(ko.utils.arrayMap(initialData,
        function (contact) {
            return {
                firstName: ko.observable(contact.firstName),
                lastName: ko.observable(contact.lastName),
                phones: ko.observableArray(ko.utils.arrayMap(contact.phones,
                    function (phone) {
                        return {
                            type: ko.observable(phone.type),
                            number:ko.observable(phone.number)
                        };
                    })
                )
            };
        }
    ));

    //[3]
    self.addContact = function () {
        self.contacts.push({
            firstName: ko.observable(),
            lastName: ko.observable(),
            phones: ko.observableArray()
        });
    };

    //[4]
    self.removeContact = function (contact) {
        self.contacts.remove(contact);
    };

    //[5]
    self.addPhone = function (contact) {
        contact.phones.push({
            type:ko.observable(),
            number:ko.observable()
        });
    };

    //[6]
    self.removePhone = function (phone) {
        $.each(self.contacts() , function () {
           this.phones.remove(phone);
        });
    };

    //[7]
    self.selfJsonData = ko.computed(
        function () {
            return JSON.stringify(ko.toJS(self.contacts()), null, 2);
        },
        this
    );
}

ko.applyBindings(new contactsModel());

[1] initialData :
此为我们初始化数据,使用的是静态数据,如果后面作深入的话,此处可以使用ajax访问api获取json数据


[2] contacts :

contacts会作为一个可监控数组,保存我们的联系人数据,在这里我们将初始化数据进行绑定,由于我们需要监控数据的变化,所以我们使用了ko.observable()来对firstName以及lastName进行监控,
对于联系人电话phones,由于这是一个数组,所以,我们需要使用ko.observableArray()来进行监控。另外,我们注意到ko.utils.arrayMap()这个函数,这个函数能起到什么作用呢,让我们来看看这个函数的签名:

ko.utils.arrayMap(array, mapping)

它的作用就是将数组的每一项进行遍历,根据自己的mapping函数进行处理来返回新的一项,从而返回成新的数组,在上面的代码中,我们对初始化数据的每一项进行遍历执行以下函数:

function (contact) {
    return {
        firstName: ko.observable(contact.firstName),
        lastName: ko.observable(contact.lastName),
        phones: ko.observableArray(ko.utils.arrayMap(contact.phones,
            function (phone) {
                return {
                    type: ko.observable(phone.type),
                    number:ko.observable(phone.number)
                };
            })
        )
    };
}

我们可以看出,这里每一项都在mapping中被我们进行了监控,对每一项的每一个字段都做了控制,简而言之,arryMap这个函数我们可以看作为一个格式化处理器。在这里,我们并没有定义基本模型,下面我们将上面的代码进行稍作改变:

我们新增两个模型:phone与contact

function phone(type, number){
    this.type = ko.observable(type);
    this.number = ko.observable(number);
}

function contact(firstName, lastName, phones){
    this.firstName = ko.observable(firstName);
    this.lastName = ko.observable(lastName);
    this.phones = ko.observableArray(phones);
}

然后将上面对于contacts的监控控制代码改为:

self.contacts = ko.observableArray(ko.utils.arrayMap(initialData,
    function (c) {
        return new contact(c.firstName, c.lastName, ko.utils.arrayMap(c.phones,
            function (p) {
                return new phone(p.type, p.number);
            }
        ));
    }
));

现在看来,对于后面即使初始化数据是从服务器上传递的,我们也可以轻易的进行格式化控制并且对其进行监控了。


[3] addContact:

添加联系人函数,由于我们队self.contacts进行了监控,那么我们在添加新联系人的时候,就只需要对self.contacts进行操作即可,这里我们就直接向其压入一个空的联系人数据即可


[4] removeContact:

删除联系人函数,理由同[3], 我们只需要remove当前的contact即可,注意一点就是我们的移除按钮中绑定了click:removeContact之后,在时间触发之后,函数会接收两个参数,一个为args,一个为sender,
args便是我们的当前轮询的contact对象


[5] addPhone:

添加联系人电话,与addContact近似,这里得到当前操作的contact对象,然后通过contact.phones获取电话号码数组,往其中压入一个新的控制项就可以了


[6] removePhone:

此处函数接收的是一个phone对象,如何移除这里的phone对象呢,这里我们需要用到jquery的$.each()函数, 来对self.contacts()进行遍历, 如果某contact的phones中存在phone,便会移除此项


[7] selfJsonData:

这是一个受依赖的监控属性,它的值取决于self.contacts, 所以当self.contacts变化的时候, selfJsonData也需要随之而改变,所以这里我们用到了 ko.computed(func, target)函数, 通过回调函数,
我们返回 self.contacts的json数据, 而target对象则为 this(self)


下面贴出我们的html代码

HTML Code

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Contacts Editor</title>
    <link rel="stylesheet" href="../css/bootstrap.min.css"/>
</head>
<body>
    <script type="text/html" id="contactListTemplate">
        <tr>
            <td>
                <input type="text" data-bind="value: firstName"/>
            </td>
            <td>
                <input type="text" data-bind="value: lastName"/>
            </td>
            <td colspan="3">
                <table  class="table table-responsive table-bordered">
                    <tbody data-bind="foreach: phones">
                        <tr>
                            <td class="col-md-4">
                                <input type="text" data-bind="value: type"/>
                            </td>
                            <td class="col-md-4">
                                <input type="text" data-bind="value: number"/>
                            </td>
                            <td class="col-md-4">
                                <a href="#" class="btn btn-danger btn-sm" data-bind="click: $root.removePhone">Remove Phone</a>
                            </td>
                        </tr>
                    </tbody>
                    <tr>
                        <td colspan="3">
                            <a href="#" class="btn btn-primary btn-sm" data-bind="click: $root.addPhone">Add Phone</a>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
        <tr>
            <td colspan="5">
                <a href="#" class="btn btn-danger btn-sm" data-bind="click: $root.removeContact">Remove Contact</a>
            </td>
        </tr>
    </script>

    <div class="container">
        <div class="row">
            <hr/>
            <a href="#" data-bind="click: addContact"  class="btn btn-primary btn-sm">Add Contact</a>
            <textarea name="contactsJsonData" id="contactsJsonData" class="col-md-12" rows="10" data-bind="text: selfJsonData"></textarea>
            <table  class="table table-responsive table-bordered">
                <thead>
                <tr>
                    <th class="col-md-3">FirstName</th>
                    <th class="col-md-3">LastName</th>
                    <th class="col-md-2">PhoneType</th>
                    <th class="col-md-2">Number</th>
                    <th class="col-md-2"></th>
                </tr>
                </thead>
                <tbody data-bind="template: {name:'contactListTemplate', foreach: contacts}">
                </tbody>
            </table>
        </div>
    </div>

    <script type="text/javascript" src="../js/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="../js/knockout-3.3.0.js"></script>
    <script type="text/javascript" src="../viewModels/contactsEditor.js"></script>
</body>
</html>

总结

虽然本例较为简单,但是却是用到了knockout.js的很多知识,如:模板绑定,模板嵌套,监控属性,依赖监控属性…也是一次较为全面的知识运用,当然,此例子还可以继续深入,比如通过api来获取服务器数据,以及将数据进入入库保存。

2
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:16217次
    • 积分:346
    • 等级:
    • 排名:千里之外
    • 原创:16篇
    • 转载:1篇
    • 译文:0篇
    • 评论:6条
    最新评论