我整理了一个使用Knockoutjs的Contacts原型MVC应用程序。我对Knockout很新,并且想知道我的设计在达到我的最终目标时是否正确。我的最终目标基本上是采用传递给我的Contacts视图的MVC模型来启动并实现以下目标:
这是我目前所处的代码细分。
查看代码
<h2>Contacts List</h2>
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-10"><h3>KO Results</h3></div>
</div>
<br />
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-10"><div id="koResults" data-bind="template: { name: 'contactSectionTmp', foreach:Contacts }"></div></div>
</div>
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-10"><a href="#" id="addContact" class="btn btn-sm btn-success" data-toggle="modal" data-target="#contactModal" data-bind="click: addContact"><strong>Add</strong></a></div>
</div>
@*I enter data in my bootstrap modal shown below and when I click "Add" the Template below appears
in div element koResults with the data I just entered. This is the desired effect I'm looking for. *@
<div class="modal" id="contactModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header" style="background-color:#B8E28D; border-color: black">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Add Contact</h4>
</div>
<div class="form-horizontal">
<form id="contactModalForm" data-bind="with:newContact,submit:add">
<div class="modal-body">
<h4>Contact</h4>
<div class="form-group">
<label class="col-sm-4 control-label">Name:</label>
<div class="col-sm-8">
<input type="text" name="Name" class="form-control" data-bind="value: Name" />
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">Address:</label>
<div class="col-sm-8">
<textarea rows="4" cols="50" name="Address" class="form-control" data-bind="value: Address"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">Phone:</label>
<div class="col-sm-8">
<input type="text" name="Phone" class="form-control" data-bind="value: Phone" />
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" id="formSubmitContact" class="btn btn-success">Add</button>
<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
</div>
</form>
</div>
</div>
</div>
</div>
@section scripts
<script type="text/javascript" src="~/Scripts/knockout-3.4.0.debug.js"></script>
<script type="text/javascript" src="~/Scripts/knockout.mapping-latest.debug.js"></script>
@* Knockout Template *@
<script id="contactSectionTmp" type="text/html">
<div class="row">
<div class="col-lg-3">Name:</div>
<div class="col-lg-9" data-bind="text: name"></div>
</div>
<div class="row">
<div class="col-lg-3">Address:</div>
<div class="col-lg-9" data-bind="text: address"></div>
</div>
<div class="row">
<div class="col-lg-3">Phone:</div>
<div class="col-lg-9" data-bind="text: phone"></div>
</div>
</script>
End Section
控制器代码
Pass in model to view here.
public ActionResult ContactsList()
{
ContactsVM mData = new ContactsVM();
mData.Contacts = new List<Contact>(){ new Contact { ID = 1, Name="Drew Lucacca", Address="782 Select St.", Phone="421-821-9101"},
new Contact {ID = 2, Name="Kevin Rosassa", Address = "222 Potter Lane", Phone="421-982-5222" },
new Contact {ID = 3, Name="Tim Kropp", Address = "440 PPG Place", Phone="725-434-8989"} };
return View(mData);
}
[HttpPost]
public ActionResult ContactCreate(Contact newContact)
{
var res = newContact;
ContactsVM myContacts = new ContactsVM();
myContacts.Contacts = new List<Contact>();
myContacts.Contacts.Add(new Contact { ID = 4, Name = "Santa Claus", Address = "440 Trump Plaza", Phone = "774-489-8989" });
return Json(myContacts);
}
Javascript代码
` //Main ViewModel
function ContactsVM(data) {
var self = this;
var mapping = {
'Contacts': {
create: function(options) {
return new Contact(options.data);
}
}
};
ko.mapping.fromJS(data, mapping, self);
self.newContact = ko.observable();
self.addContact = function() {
debugger;
self.newContact(new Contact({Name: '', Address: '', Phone: ''}));
}
self.add = function () {
debugger;
var jsData = data;
var jsData1 = ko.mapping.toJSON(self.newContact());
$.ajax({
url: '@Url.Action("ContactCreate", "Home")',
type: 'POST',
data: ko.mapping.toJSON(self.newContact()),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (jsonObject) {
self.contacts.push(new Contact(jsonObject));
}
});
// Close the modal.
$('#contactModal').modal('toggle');
};
self.cancel = function () {
// Close the modal.
$('#contactModal').modal('toggle');
};
//self.resetForm = function (formId) {
// var form = $('#' + formId);
// form.validate().resetForm();
// form.get(0).reset();
//};
};
function Contact(data) {
ko.mapping.fromJS(data, {}, this);
this.isEdit = ko.observable(false);
};
$(function () {
var jsonModel = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model));
var vm = new ContactsVM(jsonModel);
ko.applyBindings(vm);
});
联系实体
public class Contact
{
public int ID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
}
ContactsVM实体
public class ContactsVM
{
public List<Contact> Contacts { get; set; }
}
编辑#1 看到这里我知道javascript是不正确的,并注意在javascript评论中询问您是否可以帮助我确定它是否不正确应该如何。
我将代码移动到MVC视图底部的新位置,因为Javascript代码似乎找不到模型。
Javascript - 淘汰赛 - 映射错误
JavaScript运行时错误:&#39;推送&#39;未定义
self.contacts.push(new Contact(jsonObject)); &LT; ---这里发生了错误。
这里的任何帮助都将非常感谢,我相信也会帮助其他人。
答案 0 :(得分:0)
我认为根据您列出的步骤,您可能最好采用迭代方法来实现此功能。一次做一件事,让它工作,然后继续下一个项目。试图一次性解决所有问题并完全测试它是非常困难的。
第一推荐:让您的客户端模型反映您的服务器端模型。之后,事情变得更容易了。由于您使用的是ko映射,因此您的客户端模型设置变得更加容易:
var web = new HttpListener();
web.Prefixes.Add("http://www.dfdfdfdfdfd.com/");
Console.WriteLine("Listeningg..");
web.Start();
Console.WriteLine(web.GetContext());
var context = web.GetContext();
var response = context.Response;
const string responseString = "<html><body>Hello world</body></html>";
var buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.Length;
var output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
Console.WriteLine(output);
output.Close();
web.Stop();
Console.ReadKey();
然后您也可以非常轻松地创建和应用顶级视图模型:
function ContactsVM(data) {
var mapping = {
'Contacts': {
create: function(options) {
return new Contact(options.data);
}
}
};
ko.mapping.fromJS(data, mapping, this);
this.newContact = ko.observable();
}
function Contact(data) {
ko.mapping.fromJS(data, {}, this);
this.isEdit = ko.observable(false);
}
这为您提供了一个顶级视图模型,其中包含一个完全填充的Contacts observable数组属性。您可以使用模式的newContact属性添加新联系人,只需使用新的Contact实例填充它。
var vm = new ContactsVM(jsonModel);
ko.applyBindings(vm);
当您将此新联系人推送到联系人数组时,DOM将自动更新以显示新联系人,因此您不需要使用&#34; ko.renderTemplate&#34;您指定的逻辑。我想你也可以根据这个observable是否有一个值显示/隐藏模态。
第二个建议:首先尝试使用淘汰赛,如果你不能使用jQuery。我不建议使用jQuery来序列化表单值。请记住,您可以直接访问客户端模型,因此您不再依赖于DOM。 ko映射插件有一个方法{{3}}回到常规的JS对象。