在数组中使用jqAutocomplete

时间:2016-07-27 10:31:07

标签: asp.net-mvc knockout.js knockout-jqautocomplete

我正在使用jqAutocomplete插件,我想在一行表中使用它。

我无法让它发挥作用。自动填充选择标签不会出现。它只允许我输入1个字母。

我正在使用knockout映射将服务器端视图模型映射到客户端视图模型。

页面呈现正常。对于新表单 - 如本例所示 - 代码生成10个空行(未显示)。我想使用自动完成功能从JobName列的列表中选择合同。

我已将viewmodals复制到此处,缩小以便更容易理解;

父视图模型:

public class WholeViewModel : BaseViewModel
{
    public WholeViewModel(int employeeId, string name;)
        : base()
    {
        this.Lines = new List<LineViewModel>();
        this.Contracts = SessionObjectsSTAS.GetContracts().Select(x => new ContractViewModel { ContractId = x.ContractId, JobName = x.JobName, Label = x.ToString() }).ToList();
        this.EmployeeId = employeeId;
        this.Name = name;
    }

    public int EmployeeId { get; set; }
    public string Name { get; set; }
    public List<ContractViewModel> Contracts { get; set; }
}

Lines Collection由此viewmodal组成:

public class LineViewModel
{
    public LineViewModel()
    {
    }

    public LineViewModel(int key)
        : this()
    {
        this.Id = key;
        this.JobName = string.Empty;
        this.Description = string.Empty;
    }

    public int Id { get; set; }
    public int? ContractId { get; set; }
    public string JobName { get; set; }
    public string Description { get; set; }
}

ContractViewModel:

public class ContractViewModel
{
    public int ContractId { get; set; }
    public string JobName { get; set; }
    public string Label { get; set; }
}

所以我的javascript:

var lineMapping = {
    'Lines': {
        key: function (line) {
            return ko.unwrap(line.Id);
        },
        create: function (options) {
            return new LineViewModel(options.data);
        }
    }
};

LineViewModel = function (data) {
    var self = this;
    ko.mapping.fromJS(data, lineMapping, self);
};

WholeViewModel = function (data) {
    var self = this;
    ko.mapping.fromJS(data, lineMapping, self);
}; 

和我的ASP.Net Razor页面:

@using Newtonsoft.Json
@model ViewModel.WholeViewModel
@{
    var data = JsonConvert.SerializeObject(Model);
}
    <table class="table">
        <tbody data-bind="foreach: Lines">
            <tr>
                <td>
                    <input type="text"
                           data-bind="jqAuto: { source: $parent.Contracts, value: JobName, labelProp: 'Label', inputProp: 'Label', valueProp: 'ContractId' }" />
                </td>
                <td>
                    <input type="text" data-bind="value: Description"  />
                </td>
            </tr>
        </tbody>
    </table>
@section scripts
{
    @Scripts.Render("~/bundles/BootstrapJs")
    @Scripts.Render("~/bundles/jqueryui")
    @Scripts.Render("~/bundles/inputmask")
    @Scripts.Render("~/bundles/Knockout")
    <script type="text/javascript">
        var wholeViewModel = new WholeViewModel(@Html.Raw(data));
        ko.applyBindings(wholeViewModel);
    </script>
}

当我在Visual Studio中设置断点时,LineViewModel看起来像这样;

enter image description here

1 个答案:

答案 0 :(得分:2)

使用全局变量数据直接绑定源。

 <script type="text/javascript">
     var data = @Html.Raw(data);
     var wholeViewModel = new WholeViewModel(data);
     ko.applyBindings(wholeViewModel);
 </script>

映射子项,行时出现一个小错误。将其归因于Knockout documentation itself

var LineViewModel = function(data) {
    ko.mapping.fromJS(data, {}, this);
}

请注意,子项映射到空对象而不是lineMapping对象。这些对象是LineViewModel的一部分,它本身连接到lineMapping中的Lines数组。

该值应为ContractId。来源应该是data.Contracts。

<input type="text"
       data-bind="jqAuto: { 
         source: data.Contracts, 
         value: ContractId, 
         labelProp: 'Label', 
         inputProp: 'Label', 
         valueProp: 'ContractId' 
        }" 
/>