Asp.net mvc 我的淘汰代码没有更新我的视图
我使用autocomplete将名称添加到表行的动态列表中。 当我添加一个新名称时,会创建一个新行,但不会更新searchText和searchId。删除链接似乎起作用。 所以我的观点看起来像Asp.net mvc 我的淘汰代码没有更新我的视图,asp.net-mvc,knockout.js,Asp.net Mvc,Knockout.js,我使用autocomplete将名称添加到表行的动态列表中。 当我添加一个新名称时,会创建一个新行,但不会更新searchText和searchId。删除链接似乎起作用。 所以我的观点看起来像 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<SHP.Models.TrainingListEmployeesViewM
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<SHP.Models.TrainingListEmployeesViewModel>" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Bulk Training
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<form class="employeeListEditor">
<h3>Allocate or cancel training for the selected employees</h3>
<table>
<tr>
<td style="text-align: right;">Course Name</td>
<td><%: Html.EditorFor(model => model.TrainingName) %></td>
</tr>
<tr>
<td style="text-align: right;">Description (optional)</td>
<td><%: Html.TextAreaFor(
model => model.TrainingDescription, new { maxlength = "255", style = "width:400px;height:100px;" }) %></td>
</tr>
</table>
<%: Html.EditorFor(model => model.ClientEmployeeSelector) %>
<button data-bind="click: addEmployee">Add</button>
<%--<input type="hidden" name="numberOfEmployees" id="numberOfEmployees" value="<%:Model.EmployeeList.Count %>" />--%>
<div id="displayEmployees" style="margin-top:10px;display: block">
<table id="employeeDataTable" class="groupBorder">
<thead>
<tr>
<th></th>
<th>Employee</th>
</tr>
</thead>
<tbody data-bind="foreach: employees">
<tr>
<td>
<a href="#" data-bind="click: $parent.removeEmployee">Remove</a>
<input type="hidden" data-bind="value: searchId"/>
</td>
<td><span data-bind="text: searchText"></span></td>
</tr>
</tbody>
</table>
</div>
</form>
<script type="text/javascript">
function Employee(id, text) {
var self = this;
self.searchId = id;
self.searchText = text;
}
var initialData = <%= new JavaScriptSerializer().Serialize(Model) %>;
function ViewModel() {
var self = this;
self.employees = ko.observableArray(initialData.EmployeeList);
self.searchText = ko.observable(initialData.SearchText);
self.searchId = ko.observable(initialData.SearchTextId);
self.removeEmployee = function(employee) {
self.employees.remove(employee);
};
self.addEmployee = function() {
self.employees.push(new Employee(self.searchId, self.searchText));
$('#SearchText').val('');
};
self.save = function() {
ko.utils.postJson(location.href, { employees: self.employees });
};
}
ko.applyBindings(new ViewModel());
</script>
</asp:Content>
职能员工(id、文本){
var self=这个;
self.searchId=id;
self.searchText=文本;
}
var initialData=;
函数ViewModel(){
var self=这个;
self.employees=ko.observearray(initialData.EmployeeList);
self.searchText=ko.observable(initialData.searchText);
self.searchId=ko.observable(initialData.SearchTextId);
self.removeEmployee=功能(员工){
self.employees.remove(员工);
};
self.addEmployee=函数(){
self.employees.push(新员工(self.searchId,self.searchText));
$('#SearchText').val('');
};
self.save=函数(){
ko.utils.postJson(location.href,{employees:self.employees});
};
}
应用绑定(新的ViewModel());
当我单击add按钮时(我希望在它工作时删除该按钮,以便由return键触发add事件),下面的行被添加到表中
<tbody data-bind="foreach: employees">
<tr>
<td>
<a href="#" data-bind="click: $parent.removeEmployee">Remove</a>
<input type="hidden" data-bind="value: searchId" value=""/>
</td>
<td><span data-bind="text: searchText"/></td>
</tr>
</tbody>
因此,删除链接将正确显示,并且也可以正常工作。但searchId和searchText都未设置。我做错了什么?当您的代码调用
新员工(self.searchId,self.searchText)
时,您将两个观察值作为参数传递。也就是说,你传递的是被观察对象本身,而不是它们的值。因此,新员工的属性将只是对主要2个可观察对象的引用。这可能不是你想要的
您应该传递可观察对象的值(而不是可观察对象本身),如:newemployee(self.searchId(),self.searchText())
。这样,每位新员工将获得两个主要观察值的当前值的副本
此外,在许多情况下,让员工的财产能够被自己观察到是很有用的(例如,如果他们可以改变的话)
这是一把小提琴,展示了:
编辑:根据海报的评论更新了小提琴,并提供了更多信息:我不知道这是否是最好的答案,但要感谢antishok在这一过程中对我的帮助。 实际的JSON数据存储如下:
{"EmployeeList":[],"ClientEmployeeSelector":{"SearchText":null,"SearchTextId":0},"Cvm":null,"TrainingName":null,"TrainingDescription":null};
因此,SearchText和SearchTextId嵌套在ClientEmployeeSelector中。
另一个问题是这些字段上的observable被正确设置为零和null,但当它们从autocomplete更改时不会更新。
因此,我修复它的方法如下:;
职能员工(id、文本){
var self=这个;
self.searchId=id.val();
self.searchText=text.val();
}
var initialData = <%= new JavaScriptSerializer().Serialize(Model) %>;
function ViewModel() {
var self = this;
self.employees = ko.observableArray(initialData.EmployeeList);
self.searchText = ko.observable($('#SearchText'));
self.searchId = ko.observable($('#SearchTextId'));
self.removeEmployee = function(employee) {
self.employees.remove(employee);
};
self.addEmployee = function() {
self.employees.push(new Employee(self.searchId(), self.searchText()));
$('#SearchText').val('');
};
self.save = function() {
ko.utils.postJson(location.href, { employees: self.employees });
};
}
ko.applyBindings(new ViewModel());
</script>
var initialData=;
函数ViewModel(){
var self=这个;
self.employees=ko.observearray(initialData.EmployeeList);
self.searchText=ko.observable($(“#searchText”);
self.searchId=ko.observable($(“#SearchTextId”);
self.removeEmployee=功能(员工){
self.employees.remove(员工);
};
self.addEmployee=函数(){
self.employees.push(新员工(self.searchId(),self.searchText());
$('#SearchText').val('');
};
self.save=函数(){
ko.utils.postJson(location.href,{employees:self.employees});
};
}
应用绑定(新的ViewModel());
现在我不知道这是否是最好的答案,但据我所知,它是有效的。好的,这是我的第二个答案,考虑到antishok对我第一个答案的有效批评。我遇到的问题是,我将变量initialData设置为模型。但是,自动完成字段不在模型中。 这就是我脚本中的解决方案
<script type="text/javascript">
function Employee(id, text) {
var self = this;
self.searchTextId = ko.observable(id);
self.searchText = ko.observable(text);
}
$(document).ready(function () {
$('#SearchText').attr("data-bind", "value: autocompleteSearchText");
$('#SearchTextId').attr("data-bind", "value: autocompleteSearchTextId");
var initialData = <%= new JavaScriptSerializer().Serialize(Model) %>;
var autocompleteData = { "autocompleteSearchTextId": 0, "autocompleteSearchText": null };
function ViewModel() {
var self = this;
self.employees = ko.observableArray(initialData.EmployeeList);
self.autocompleteSearchText = ko.observable(autocompleteData.autocompleteSearchText);
self.autocompleteSearchTextId = ko.observable(autocompleteData.autocompleteSearchTextId);
self.removeEmployee = function(employee) {
self.employees.remove(employee);
};
self.addEmployee = function() {
self.employees.push(new Employee(self.autocompleteSearchTextId(), self.autocompleteSearchText()));
self.autocompleteSearchText('');
};
self.save = function() {
var trainingName = $("#TrainingName").val();
var trainingDescription = $("#TrainingDescription").val();
ko.utils.postJson(location.href, { employees: self.employees, trainingName: trainingName, trainingDescription: trainingDescription });
};
}
ko.applyBindings(new ViewModel());
});
</script>
职能员工(id、文本){
var self=这个;
self.searchTextId=ko.可观察(id);
self.searchText=ko.observable(文本);
}
$(文档).ready(函数(){
$('SearchText').attr(“数据绑定”,“值:自动完成搜索文本”);
$('SearchTextId').attr(“数据绑定”,“值:autocompleteSearchTextId”);
var initialData=;
var autocompleteData={“autocompleteSearchTextId”:0,“autocompleteSearchText”:null};
函数ViewModel(){
var self=这个;
self.employees=ko.observearray(initialData.EmployeeList);
self.autocompleteSearchText=ko.observable(autocompleteData.autocompleteSearchText);
self.autocompleteSearchTextId=ko.observable(autocompleteData.autocompleteSearchTextId);
self.removeEmployee=功能(员工){
self.employees.remove(员工);
};
self.addEmployee=函数(){
self.employees.push(新员工(self.autocompleteSearchTextId(),self.autocompleteSearchText());
self.autocompleteSearchText(“”);
};
self.save=函数(){
var trainingName=$(“#trainingName”).val();
var trainingDescription=$(“#trainingDescription”).val();
ko.utils.postJson(location.href,{employees:self.employees,trainingName:trainingName,trainingDescription:trainingDescription});
};
}
应用绑定(新的ViewModel());
});
我使用JQuery输入