我是新来的美人,我有使用映射插件,因为我不明白它是如何映射我的JSON数据的问题。
这类似于是什么在我的程序样本JSON数据:
contact: {
name : 'John',
email : 'address@domain.com',
phones : [{
phoneType : 'Home Phone',
phoneNumber: '999-888-777'},
{
phoneType : 'Business Phone',
phoneNumber: '444-888-777'},
}]
}
正如你所看到的,这个JSON数据包含手机的数组。
我用淘汰赛映射插件,我可以绑定“名”,“邮件”和环形的电话号码:直到我试图让在phoneNumber的一个ko.compute这是一个对象,在没有麻烦“的foreach手机”阵列手机。
@section scripts
{
<script src="~/ViewModels/ContactModel.js"></script>
<script type="text/javascript">
var viewModel = new ContactModel(@Html.Raw(Model.ToJson()));
$(document).ready(function () {
ko.applyBindings(viewModel);
});
</script>
<label>Name</label><input data-bind="value: name" />
<label>Email</label><input data-bind="value: email" />
<label>Phones</label>
<table>
<tbody data-bind="foreach: phones">
<tr>
<td><strong data-bind='text: phoneType'></strong></td>
<td><input data-bind='value: phoneNumber' /></td>
</tr>
/tbody>
</table>
这是ContactModel.js
var ContactModel = function (data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
self.reformatPhoneNumber = ko.computed(function(){
var newnumber;
newnumber = '+(1)' + self.phones().phoneNumber;
return newnumber;
});
};
对于可视化表示,这是怎么这个样子,现在:
Name: John
Email: address@domain.com
Phones:
<--foreach: phones -->
Home Phone: 999-888-777
Business Phone: 444-888-777
什么即时试图做的是重新格式化phoneNumber的,以显示它是这样的:
Name: John
Email: address@domain.com
Phones:
<--foreach: phones -->
Home Phone: (+1)999-888-777
Business Phone: (+1)444-888-777
我试图通过地方phoneNumber的在我这样的结合使用reformatPhoneNumber做到这一点:
<table>
<tbody data-bind="foreach: phones">
<tr>
<td><strong data-bind='text: phoneType'></strong></td>
<td><input data-bind='value: $root.reformatPhoneNumber' /></td>
</tr>
/tbody>
</table>
但是,当我这样做,reformatPhoneNumber的价值不会出现。 我读到这里的地方,我必须让我的observableArray内的对象也观察到,因为ko.mapping默认不这样做。 但我不能想象如何做到这一点,因为我期待ko.mapping插件为我自动完成所有的工作,因为我是新来这个jslibrary。
任何帮助将不胜感激。 非常感谢你!!
您使用的命名(一个名为计算的reformatPhoneNumber
)建议,你认为computeds的功能。 虽然他们在技术上,功能,其代表的值。 把他们当作价值,就像你对待观测。 在你的情况,这意味着它应该被称为更像formattedPhoneNumber
,应该活的电话号码的属性,而不是作为联系人的属性。
分开你的模型转换成可以从原始数据本身引导个体单位。
在你的模型层次信息的最小单位是一个电话号码:
function PhoneNumber(data) {
var self = this;
self.phoneType = ko.observable();
self.phoneNumber = ko.observable();
self.formattedPhoneNumber = ko.pureComputed(function () {
return '+(1) ' + ko.unwrap(self.phoneNumber);
});
ko.mapping.fromJS(data, PhoneNumber.mapping, self);
}
PhoneNumber.mapping = {};
在层次结构接下来是一个接触。 它包含电话号码。
function Contact(data) {
var self = this;
self.name = ko.observable();
self.email = ko.observable();
self.phones = ko.observableArray();
ko.mapping.fromJS(data, Contact.mapping, self);
}
Contact.mapping = {
phones: {
create: function (options) {
return new PhoneNumber(options.data);
}
}
};
接下来是联系人列表(或者电话簿),它包含联系人:
function PhoneBook(data) {
var self = this;
self.contacts = ko.observableArray();
ko.mapping.fromJS(data, PhoneBook.mapping, self);
}
PhoneBook.mapping = {
contacts: {
create: function (options) {
return new Contact(options.data);
}
}
};
现在,您可以通过实例化一个电话簿对象创建整个对象图:
var phoneBookData = {
contacts: [{
name: 'John',
email: 'address@domain.com',
phones: [{
phoneType: 'Home Phone',
phoneNumber: '999-888-777'
}, {
phoneType: 'Business Phone',
phoneNumber: '444-888-777'
}]
}]
};
var phoneBook = new PhoneBook(phoneBookData);
通读映射插件的文档 。
展开下面的代码片段,看看它的工作。
function PhoneBook(data) { var self = this; self.contacts = ko.observableArray(); ko.mapping.fromJS(data, PhoneBook.mapping, self); } PhoneBook.mapping = { contacts: { create: function (options) { return new Contact(options.data); } } }; // ------------------------------------------------------------------ function Contact(data) { var self = this; self.name = ko.observable(); self.email = ko.observable(); self.phones = ko.observableArray(); ko.mapping.fromJS(data, Contact.mapping, self); } Contact.mapping = { phones: { create: function (options) { return new PhoneNumber(options.data); } } }; // ------------------------------------------------------------------ function PhoneNumber(data) { var self = this; self.phoneType = ko.observable(); self.phoneNumber = ko.observable(); self.formattedPhoneNumber = ko.pureComputed(function () { return '+(1) ' + ko.unwrap(self.phoneNumber); }); ko.mapping.fromJS(data, PhoneNumber.mapping, self); } PhoneNumber.mapping = {}; // ------------------------------------------------------------------ var phoneBook = new PhoneBook({ contacts: [{ name: 'John', email: 'address@domain.com', phones: [{ phoneType: 'Home Phone', phoneNumber: '999-888-777' }, { phoneType: 'Business Phone', phoneNumber: '444-888-777' }] }] }); ko.applyBindings(phoneBook);
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script> <ul data-bind="foreach: contacts"> <li> <div data-bind="text: name"></div> <div data-bind="text: email"></div> <ul data-bind="foreach: phones"> <li> <span data-bind="text: phoneType"></span>: <span data-bind="text: formattedPhoneNumber"></span> </li> </ul> </li> </ul> <hr /> Model data: <pre data-bind="text: ko.toJSON(ko.mapping.toJS($root), null, 2)"></pre> Viewmodel data: <pre data-bind="text: ko.toJSON($root, null, 2)"></pre>