我是一名 C# MVC 开发人员,希望将我的客户端 JavaScript 从一堆事件处理程序发展为一个更有条理的系统,所以我开始研究 knockoutjs。最初它看起来很棒,关于如何将它放入我的生产环境的想法正在迅速形成。我已经尝试了一些基本原则,所有这些原则都非常有效,没有问题。我想尝试一些更复杂的东西(这是特定于我正在从事的项目的),但我无法让它工作。
我尝试搜索其他示例,但并没有真正找到任何匹配的内容。
我想做的是将对象列表绑定到客户端。在这个例子中,我使用了一个人列表,我在页面上显示了这个列表,并且想在一个 ajax 请求上更新页面上的所有人(这个例子纯粹是为了测试而捏造的,但原理就是我后)。
我正在使用 knockoutjs 映射插件为我做模型映射
我的 C# 代码
public class HomeController : Controller
{
public ActionResult Index()
{
List<Person> people = new List<Person>()
{
new Person()
{
FirstName = "Neil",
LastName = "Diamond"
},
new Person()
{
FirstName = "Bob",
LastName = "Seager"
},
new Person()
{
FirstName = "Tom",
LastName = "Jones"
}
};
return View(people);
}
public JsonResult UpdateNames()
{
Random r = new Random();
var num = r.Next(1, 100);
List<Person> people = new List<Person>()
{
new Person()
{
FirstName = string.Concat("Neil", num.ToString()),
LastName = string.Concat("Diamond", num.ToString())
},
new Person()
{
FirstName = string.Concat("Bob", num.ToString()),
LastName = string.Concat("Seager", num.ToString())
},
new Person()
{
FirstName = string.Concat("Tom", num.ToString()),
LastName = string.Concat("Jones", num.ToString())
}
};
return Json(people, JsonRequestBehavior.AllowGet);
}
}
我的观点
@model List<TestingKnockout.Models.Person>
@{
ViewBag.Title = "Home Page";
}
@for (int i = 0; i < Model.Count; i++)
{
<p>Firstname: <strong data-bind="text: [@i].FirstName"></strong></p>
<p>Lastname: <strong data-bind="text: [@i].LastName"></strong></p>
<hr />
}
@section scripts
{
<script src="~/Scripts/knockout-2.1.0.js"></script>
<script src="~/Scripts/knockout.mapping.js"></script>
<script type="text/javascript">
var viewModel = {};
$.ajax({
url: "/Home/UpdateNames",
cache: false,
success: function (data) {
viewModel = ko.mapping.fromJS(data);
ko.applyBindings(viewModel);
}
});
setInterval(function () {
$.ajax(
{
url: "/Home/UpdateNames",
cache: false,
success: function (data) {
ko.mapping.fromJS(data, viewModel);
}
});
}, 5000);
</script>
}
任何帮助将不胜感激,或者如果我遗漏了明显的东西,或者如果这个问题已经出现,请指出我正确的方向。
问候
编辑
从 Tomas 和 Rodney 的两个答案来看,我似乎错误地假设了一些淘汰赛的行为。Knockout 必须从整个模型作为 JSON 开始,然后从那里更新。我希望用初始数据呈现 HTML,然后淘汰以处理更新,但我认为我的方法不正确。使用 Tomas 的 HTML 和 Rodney 的代码(对 json 序列化和可观察的人员进行了细微更改),我将视图代码更改为以下内容,现在一切似乎都运行良好
@model List<TestingKnockout.Models.Person>
@{
ViewBag.Title = "Home Page";
}
<div data-bind="foreach: people">
<p>Firstname: <strong data-bind="text: FirstName"></strong></p>
<p>Lastname: <strong data-bind="text: LastName"></strong></p>
<hr />
</div>
@section scripts
{
<script src="~/Scripts/knockout-2.1.0.js"></script>
<script src="~/Scripts/knockout.mapping.js"></script>
<script type="text/javascript">
var viewModel = {
people: ko.mapping.fromJS(@Html.Raw(Json.Encode(Model)))
};
ko.applyBindings(viewModel);
setInterval(function () {
$.ajax(
{
url: "/Home/UpdateNames",
cache: false,
success: function (data) {
ko.mapping.fromJS(data, viewModel.people);
}
});
}, 5000);
</script>
}
我想把答案交给托马斯和罗德尼。不得不选择,我认为罗德尼帮助了最对不起托马斯。