我正在尝试从视图更新后刷新包含的角色行。 UI使用Knockout,后端是ASP NET MVC。我遇到的问题是,当我拨打GetRoles()
时,我的更新信息没有刷新。但是,当我拨打self.Roles(data.RolesList)
时,它会起作用。以下是我的实施。
视图:包含一个TABLE。单击TR时,将使用所选行的值填充输入。
@model ExpensesOrganiser4.ViewModels.RoleIndexViewModel
@section scripts{
@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/jqueryui")
@Styles.Render("~/Content/themes/base/css")
<script src="~/Scripts/knockout-2.1.0.js" type="text/javascript"></script>
<script src="~/Scripts/knockout.mapping-latest.js" type="text/javascript"></script>
<script src="~/Scripts/Application/role.js" type="text/javascript"></script>
<script type="text/javascript">
var kovm = new RoleVM(@Html.Raw(Json.Encode(Model)));
ko.applyBindings(kovm);
</script>
@*<script type="text/javascript">
RoleVM = ko.mapping.fromJS(@Html.Raw(Json.Encode(Model)));
</script>*@
}
<h2>Index</h2>
<p>
<a data-bind="click: DisplayNew">Create New</a>
</p>
<!-- //TABLE containing rows of roles -->
<table border="1">
<thead>
<tr>
<th>@Html.DisplayNameFor(model => model.Rvm.RoleID)</th>
<th>@Html.DisplayNameFor(model => model.Rvm.RoleName)</th>
<th>@Html.DisplayNameFor(model => model.Rvm.Description)</th>
<th>@Html.DisplayNameFor(model => model.Rvm.ApplicationName)</th>
<th>@Html.DisplayNameFor(model => model.Rvm.ApplicationDescription)</th>
<th data-bind="visible: false"></th>
</tr>
</thead>
<tbody data-bind="foreach: Roles">
<tr data-bind="click: $root.GetSelectedRole" id="updtr">
<td><span data-bind="text: RoleID"></span></td>
<td><span data-bind="text: RoleName"></span></td>
<td><span data-bind="text: Description"></span></td>
<td><span data-bind="text: ApplicationName"></span></td>
<td><span data-bind="text: ApplicationDescription"></span></td>
<td data-bind="visible: false"><span data-bind="text: ApplicationID"></span></td>
</tr>
</tbody>
</table>
<!-- //END TABLE containing rows of roles -->
<!-- INPUTS populated when <TR> is clicked --->
<table data-bind="visible: ReadOnlyMode">
<tr>
<td><label for="RoleID">Role ID:</label></td>
<td><input data-bind="value: RoleID" type="text" id="RoleID" /></td>
</tr>
<tr>
<td><label for="RoleName">Role Name:</label></td>
<td><input data-bind="value: RoleName" type="text" id="RoleName" /></td>
</tr>
<tr>
<td><label for="Description">Role Description:</label></td>
<td><input data-bind="value: Description" type="text" id="Description" /></td>
</tr>
<tr>
<td><label for="ApplicationName">Application:</label></td>
<!--<td>@Html.DropDownList("cboApplicationName", Model.ApplicationsSelectList, new Dictionary<string, object> {{ "data-bind", "value: ApplicationID"}})</td>-->
<td><select data-bind="options: ApplicationsList, optionsText: 'AppName', optionsValue: 'AppID', value: ApplicationID" id="cboApplications"></select></td>
</tr>
<tr>
<td><label for="ApplicationDescription">Application Description:</label></td>
<td><input data-bind="value: SelectedApplication" type="text" id="ApplicationDescription" /></td>
</tr>
</table>
<button data-bind="visible: DisplayUpdateRoleButton, click: UpdateRole" id="btnUpdate">Update</button>
<button data-bind="visible: DisplayDeleteRoleButton" id="btnDelete">Delete</button>
<div id="dialog-confirm" title="Success">Success.</div>
Knockout的定义:刷新方法function GetRoles()
。 thrownerror
为SyntaxError: Unexpected token <
var self; //declare self outside the view model logic.
var RoleVM = function (data) {
self = this;
ko.mapping.fromJS(data, {}, self);
self.EditFields = ko.observable(false);
self.ReadOnlyMode = ko.observable(true);
self.DisplayEditRoleButton = ko.observable(true);
self.DisplayUpdateRoleButton = ko.observable(false);
self.DisplayDeleteRoleButton = ko.observable(false);
self.Roles = ko.observableArray(data.RolesList);
self.ApplicationsList = ko.observableArray(data.ApplicationsList);
self.RoleID = ko.observable();
self.RoleName = ko.observable();
self.Description = ko.observable();
self.ApplicationName = ko.observable();
self.ApplicationDescription = ko.observable();
self.ApplicationID = ko.observable();
self.SelectedApplication = ko.observable("");
self.ApplicationID.subscribe(function (value) {
self.SelectedApplication(self.ApplicationsList()[value - 1].AppDesc);
});
self.GetSelectedRole = function (role) {
self.RoleID(role.RoleID);
self.RoleName(role.RoleName);
self.Description(role.Description);
self.ApplicationName(role.ApplicationName);
self.ApplicationDescription(role.ApplicationDescription);
self.ApplicationID(role.ApplicationID);
self.DisplayUpdateRoleButton(true);
self.DisplayDeleteRoleButton(true);
};
self.UpdateRole = function () {
UpdateSelectedRole();
};
self.DisplayNew = function () {
self.RoleID("");
self.RoleName("");
self.Description("");
self.DisplayDeleteRoleButton(false);
};
};
//HERE. This is not working
function GetRoles() {
debugger;
$.ajax({
cache: false,
type: "GET",
url: "/Roles",
dataType: "JSON",
success: function (vm) {
debugger;
console.log(vm);
self.Roles(vm.RolesList); //put response in self.Roles Observable array
},
error: function (xhr, ajaxOptions, thrownError) {
alert("Failed to retrieve roles. " + "xhr.status: " + xhr.status + "thrownError: " + thrownError);
//console.log(JSON.stringify(xhr));
console.log(xhr.responseText);
//console.log("AJAX error: " + ajaxOptions + ' : ' + thrownError);
}
});
}
function UpdatedRoleInfo() {
this.RoleID;
this.RoleName;
this.RoleDescription;
this.ApplicationID;
}
function UpdateSelectedRole() {
var updatedRoleInfo = new UpdatedRoleInfo();
updatedRoleInfo.RoleID = self.RoleID();
updatedRoleInfo.RoleName = self.RoleName();
updatedRoleInfo.Description = self.Description();
updatedRoleInfo.ApplicationID = self.ApplicationID();
//updatedRoleInfo.ApplicationID = $("#cboApplications").val();
var url = "/Roles/Edit";
$.ajax({
cache: false,
type: "POST",
url: "/Roles/Edit",
data: updatedRoleInfo,
success: function (data, textStatus) {
UpdateRoleComplete(data);
GetRoles(); //Fails when I call this.
//self.Roles(data.RolesList); //Works when I call this.
},
error: function (xhr, ajaxOptions, thrownError) {
alert("Failed to update. " + "xhr.status: " + xhr.status + "xhr.responseText: " + xhr.responseText);
}
});
}
function UpdateRoleComplete(result) {
self.EditFields(false);
self.ReadOnlyMode(true);
self.DisplayEditRoleButton(true);
self.DisplayUpdateRoleButton(true);
//self.OriginalRoleName(result.ViewModel.RoleName);
//self.OriginalDescription(result.ViewModel.Description);
$("#dialog-confirm").dialog("open");
}
$("#dialog-confirm").dialog({
autoOpen: false,
resizable: false,
modal: true,
draggable: true,
width: 300,
buttons: {
"OK": function () {
$(this).dialog("close");
}
}
});
MVC:
public ActionResult Index()
{
RoleIndexViewModel viewModel = new RoleIndexViewModel();
Roles r = new Roles();
viewModel = r.CreateRoleIndexViewModel();
return View(viewModel);
}
[HttpPost]
public ActionResult Edit(RoleViewModel rvm)
{
RoleIndexViewModel viewModel = new RoleIndexViewModel();
Roles r = new Roles();
if (ModelState.IsValid)
{
using (db)
{
tblRole role = db.tblRoles.Single(t => t.RoleID == rvm.RoleID);
role.RoleName = rvm.RoleName;
role.Description = rvm.Description;
role.ApplicationID = rvm.ApplicationID;
db.ObjectStateManager.ChangeObjectState(role, EntityState.Modified);
db.SaveChanges();
}
viewModel = r.CreateRoleIndexViewModel();
}
return Json(viewModel, JsonRequestBehavior.AllowGet);
}
问题是由嵌套的AJAX调用引起的,即在UpdateSelectedRole()
及其中GetRoles()
吗?
由于
答案 0 :(得分:0)
在你的ajax调用中首先清除roles数组然后像这样传递新的结果
self.Roles([]);
self.Roles(vm.RolesList);
同时更改GetRoles
功能
self.GetRoles = () {
// your code here
}
答案 1 :(得分:0)
因为self.Roles
不是您要设置的函数中的全局/。
您可以进行以下更改,看看它是否有效?
更改
function UpdateSelectedRole() {
var updatedRoleInfo = new UpdatedRoleInfo();
updatedRoleInfo.RoleID = self.RoleID();
updatedRoleInfo.RoleName = self.RoleName();
updatedRoleInfo.Description = self.Description();
updatedRoleInfo.ApplicationID = self.ApplicationID();
//updatedRoleInfo.ApplicationID = $("#cboApplications").val();
var url = "/Roles/Edit";
$.ajax({
cache: false,
type: "POST",
url: "/Roles/Edit",
data: updatedRoleInfo,
success: function (data, textStatus) {
UpdateRoleComplete(data);
GetRoles().success(function(data){
self.Roles(data.RolesList);
});
//self.Roles(data.RolesList); //Works when I call this.
},
error: function (xhr, ajaxOptions, thrownError) {
alert("Failed to update. " + "xhr.status: " + xhr.status + "xhr.responseText: " + xhr.responseText);
}
});
}
function GetRoles() {
return $.ajax({
cache: false,
type: "GET",
url: "/Roles",
dataType: "JSON"
});
}
GetRoles返回我在UpdateSelectedRole中解析的promise并填充了self.Roles