我正在使用Knockout 2.2.1,JQuery 1.9.1和Ryan Niemeyer的Knockout-jqAutoComplete 0.4.3。
该应用程序允许用户将联系人添加到联系人列表中。联系信息来自可能的联系人列表。
我们使用span来显示页面加载时数据库和数据模型中存在的联系人的名称。当用户单击该名称时,他们有机会编辑或删除该联系人。我们隐藏跨度并在其位置显示输入字段。此字段是“自动完成”字段,它应显示联系人的姓名。
用户还可以单击按钮添加新联系人,这会添加一个带有输入字段的新行,该输入字段也使用自动完成功能。
单击保存按钮时,用户编辑或添加的信息将保留。
问题
当用户进入编辑模式时,输入显示ID而不是名称。
此处是页面加载时显示的an image数据,此处切换到编辑模式时为what it looks like。在第二张图片中,我们希望它显示“Doe,John”而不是数据库中的主键。
使用旧版本的Knockout-jqAutoComplete,这不是问题。 (我们更新到当前版本,因为还有其他问题。)我找不到它的版本号,但它被包括一个Razor partial,“_ jqueryAutoCompleteBinding.cshtml”使用。这个旧版本的绑定是:
//Deprecated, no longer in use.
<input data-bind="jqAuto: { autoFocus: false }, jqAutoSource: optionsProfessionalsAuto, jqAutoQuery: getProfessionals, jqAutoValue: ProfessionalId, jqAutoSourceLabel: 'displayName', jqAutoSourceInputValue: 'Name', jqAutoSourceValue: 'Id'" class="edit-data Name" />
我们现在使用的绑定是:
<input data-bind="jqAuto: { source: getProfessionals, value: ProfessionalId, valueProp: 'ProfessionalId', labelProp: 'Name', inputProp: 'Name', options: { autoFocus: false } }"class="edit-data Name" />
以下是AppViewModel的相关部分:
function AppViewModel() {
//{...}
self.addProfessionalContact = function () {
var skip = this.ProfessionalContacts().length * 14 - 1; // rows * columns - 1
this.ProfessionalContacts.push({
Name: ko.observable(''),
Specialty: ko.observable(''),
City: ko.observable(''),
State: ko.observable(''),
ProfessionalId: ko.observable(),
optionsProfessionalsAuto: ko.observableArray() //deprecated?
});
WireUpEditGridEvents();
SetDisabled();
RegisterDatePicker();
WireUpPostAddEvents(skip, 'professionalContacts');
$("#professionalContacts tr").last().find(".display-data").hide();
//{...}
}
(编辑1) 以下是GetProfessionals,请求:
function getProfessionals(searchTerm, sourceArray) {
try {
$.ajax({
type: "GET"
, contentType: 'application/json; charset=utf-8'
, url: '@Url.Action(MVC.Professional.ActionNames.GetProfessionals, MVC.Professional.Name)?searchTerm=' + searchTerm
, dataType: "json"
, success: function (data) {
var result = [];
for (var i = 0; i < data.length; i++) {
var specialty = data[i].Specialty ? data[i].Specialty + " - " : "";
result.push({ Name: data[i].Name + " (" + specialty + data[i].City + ", " + data[i].State + ")", ProfessionalId: data[i].ProfessionalId });
}
sourceArray(result);
}
}
)
.fail(function () { $.unblockUI(); $.growlUI('Error', 'Failed to get professionals. Unknown error.'); });
} catch (e) {
$.unblockUI();
throw e;
}
(编辑2)
我想我确实需要进一步澄清。
getProfessionals函数返回ProfessionalContactEditViewModel类型的列表。该类包含几个属性:
public class ProfessionalContactEditViewModel
{
public int? ClientContactId { get; set; }
public int ProfessionalId { get; set; }
public string Name { get; set; }
public string Specialty { get; set; }
public string Phone { get; set; }
public string Fax { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public bool Send { get; set; }
public bool ReferredBy { get; set; }
public bool Delete { get; set; }
//Added based on RPNiemeyer's response
//public NameIdViewModel ProfessionalNameId
//{
// get
// {
// return new NameIdViewModel()
// {
// Name = this.Name,
// Id = this.ProfessionalId,
// };
// }
// set
// {
// this.Name = value.Name;
// this.ProfessionalId = value.Id ?? default(int);
// }
//}
}
根据RP的回答,我添加了一个NameIdViewModel obj。返回Name和ProfessionalId。但是,这并没有变成一个可观察的嵌套对象,所以我们现在从getProfessionals传递整个ProfessionalContactViewModel:
result.push(ko.toJSON(data));
我从输入绑定中删除了valueProp;否则读取与以前相同,但我在编辑联系人时仍然看到一个数字。
当按名称搜索联系人时,浏览器选项卡也会冻结几秒钟,并显示一个完全空白的列表。这两个新问题的前者可能是由于数据量较大。