我使用Knockout JS和映射插件将MVC视图模型映射到viewmodel属性;
var viewModel = function() {
var self = this;
self.EntityKey = 0;
self.observables = ko.observable();
self.RoleName = ko.observable("");
// CRUD Actions
self.getPaged = function (page) {
$.ajax({
url: "/Core/Authentication/Role/UpdateIndex",
dataType: 'json',
data: { pageNumber: page },
success: function (result) {
self.observables = ko.mapping.fromJS(result);
},
});
};
this.remove = function (data) {
$.ajax({
type: "POST",
url: "/Core/Authentication/Role/Delete",
dataType: 'json',
data: { userId: data.EntityKey() },
success: function (result) {
self.getPaged(self.observables.CurrentPage);
toastr.success(result);
},
});
};
this.update = function (data) {
$.ajax({
type: "POST",
url: "/Core/Authentication/Role/Update",
dataType: 'json',
data: ko.toJSON(this),
success: function (result) {
toastr.success(result);
},
});
};
this.create = function () {
$.ajax({
type: "POST",
url: "/Core/Authentication/Role/Create",
dataType: 'json',
data: ko.toJSON(this),
success: function (result) {
self.getPaged(self.observables.CurrentPage);
toastr.success(result);
self.RoleName("");
},
});
};
self.getPaged(1);
}
$(function () {
var vm = new viewModel();
ko.applyBindings(vm);
});
这是我的观点;
<table data-bind="visible: observables.PageItems">
<tr>
<th>@AuthRes.Resource.EntityKey</th>
<th>@AuthRes.Resource.RoleName</th>
<th>@AuthRes.Resource.Update</th>
<th>@AuthRes.Resource.Delete</th>
</tr>
<tr data-bind="foreach: observables.PageItems">
<td><span data-bind="text: $data.EntityKey" /></td>
<td><input type="text" data-bind="value: $data.RoleName" /></td>
<td><a data-bind="click: $root.update.bind($data)">@AuthRes.Resource.Update</a></td>
<td><a href='#' data-bind="click: $root.remove.bind($data)">@AuthRes.Resource.Delete</a></td>
</tr>
</table>
<h2>@AuthRes.Resource.CreateNew</h2>
<table>
<tr>
<th>@AuthRes.Resource.RoleName</th>
<th></th>
</tr>
<tr>
<td>
<input type="text" required="required" data-bind="value: RoleName" />
</td>
<td>
<a href="#" data-bind="click: $root.create" />@AuthRes.Resource.Submit</a>
</td>
</tr>
</table>
viewModel.observables正在正确更新,数据是正确的,但由于某种原因,它不能绑定到observables.PageItems的foreach。
知道我做错了吗?
答案 0 :(得分:1)
<强> 1。 foreach
将适用于您标记的子项。
使用您的代码
<tr data-bind="foreach: observables.PageItems">
<td><span data-bind="text: $data.EntityKey" /></td>
<td><input type="text" data-bind="value: $data.RoleName" /></td>
<td>
<a data-bind="click: $root.update.bind($data)">@AuthRes.Resource.Update</a>
</td>
<td>
<a href='#'
data-bind="click: $root.remove.bind($data)">@AuthRes.Resource.Delete</a>
</td>
</tr>
只会创建一个tr
。
尝试使用无容器语法:
<!-- ko foreach: observables.PageItems -->
<tr>
<td><span data-bind="text: $data.EntityKey" /></td>
<td><input type="text" data-bind="value: $data.RoleName" /></td>
<td>
<a data-bind="click: $root.update.bind($data)">@AuthRes.Resource.Update</a>
</td>
<td>
<a href='#'
data-bind="click: $root.remove.bind($data)">@AuthRes.Resource.Delete</a>
</td>
</tr>
<!-- /ko -->
2.另外,检查您可能想要尝试的visible
绑定
<table data-bind="visible: observables.PageItems().length > 0">
3.您的映射语法不正确
当您声明self.observables = ko.observable();
并绑定它时,knockout将创建一个链接,以便在您更新self.observables
时html将更新。
现在当你执行此操作self.observables = ko.mapping.fromJS(result);
时,它不会更新,它会中断链接并分配一个新的observable。这意味着html将不再更新。
如果您在绑定(self.observables = ko.mapping.fromJS(result);
)之前执行此语法ko.applyBindings
是正确的,但您尚未获得数据。
您可以使用if
绑定来检查您的数据是否已加载。这将阻止在未满足if
条件时创建绑定链接(每次条件更改为true时都将重新创建绑定)。这样你的绑定就不会破坏。
<!-- ko if: hasInit -->
<table data-bind="visible: observables.PageItems">
<!-- ... -->
</table>
<!-- /ko --->
和js
var viewModel = function() {
var self = this;
self.EntityKey = 0;
self.hasInit = ko.observable(false);
//self.observables = ko.observable(); //REMOVE THIS LINE,
//observables will be created after
self.RoleName = ko.observable("");
// CRUD Actions
self.getPaged = function (page) {
$.ajax({
url: "/Core/Authentication/Role/UpdateIndex",
dataType: 'json',
data: { pageNumber: page },
success: function (result) {
if (typeof self.observables === 'undefined') { //first call
self.observables = ko.mapping.fromJS(result);
self.hasInit(true);
} else //updates
ko.mapping.fromJS(results, self.observables);
},
});
};
}