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

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来获取服务器数据,以及将数据进入入库保存。

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值