您的位置:首页 > Web前端 > JavaScript

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

2015-07-08 14:56 639 查看

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来获取服务器数据,以及将数据进入入库保存。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: