简体   繁体   English

淘汰赛仅在第一时间有效

[英]Knockout only works first time

I am having some trouble with knockout and hoped someone here might be able to help. 我在淘汰赛上遇到了一些麻烦,希望这里有人可以提供帮助。

I have two jQuery functions. 我有两个jQuery函数。 One which, using knockout, binds to a single element on the page.The other binds to the rest of the elements and then calls the first function. 一个使用敲除功能绑定到页面上的单个元素,另一个使用绑定到其余元素,然后调用第一个函数。

The data is taken from an AJAX request which returns Json. 数据取自返回Json的AJAX请求。

The problem I am having is to doing with pGroups list. 我遇到的问题是与pGroups列表有关。 It works fine the first time but then when you click again it fails and needs a refresh to work again. 第一次运行正常,但随后再次单击时失败,需要刷新才能再次运行。

The Console error is: NotFoundError: Node was not found 控制台错误是:NotFoundError:找不到节点

EDIT: Updated code to show progress 编辑:更新代码以显示进度

The jQuery is: jQuery是:

//Load user data into the action window when a user is selected
$('.ListUserLink').click(function () {

    var url = '@Url.Action("DisplayUser", "AjaxUser")' + '?UserId=' + $(this).attr("UserId") + '&UserNum=' + $(this).attr("UserNum") + "&SectId=" + $(this).attr("Sect");

    $.ajax({
        url: url,
        contentType: "application/json; charset=utf-8",
        type: 'POST',
        context: this,
        timeout: 60000,
        dataType: 'json',
        tryCount: 0,
        retryLimit: 3,
        success: function (data) {
            //ko.applyBindings(new UserViewModel(data));
            viewModel.user = new userModel(data);
        },
        error: function (httpRequest, textStatus, errorThrown) {
            alert("Error");
        }
    });
});

//Load sections on department index change
$("#ddbDepartments").change(function () {
    var url = '@Url.Action("GetSectionsByDept", "AjaxUser")' + '?deptId=' + $(this).val();
    $.ajax({
        url: url,
        contentType: "application/json; charset=utf-8",
        type: 'POST',
        context: this,
        timeout: 60000,
        dataType: 'json',
        tryCount: 0,
        retryLimit: 3,
        success: function (data) {
            //ko.applyBindings(new SectionViewModel(data), $(".SectionsDDB")[0]);
            viewModel.sections = new userModel(data);
        },
        error: function (httpRequest, textStatus, errorThrown) {
            alert("Error");
        }
    });
});



//Assign Section details to fields
function sectionsModel(data) {
    this.sectionList = ko.observableArray(data.SectionList);
//      this.sections = this.sectionList;
//      this.selectedItem = parseInt($("#OldSectionId").value);
};

//Assign user details to fields
function userModel(data) {

    this.fullName = ko.observable(data.FirstName + " " + data.Surname);

    this.firstName = ko.observable(data.FirstName);
    this.surname = ko.observable(data.Surname);
    this.usernum = ko.observable(data.UserNum);

    //Assign JobTitle Dropdown and selected value
    this.jobTitlesList = ko.observableArray(data.TitlesList);
    this.jobTitles = this.jobTitlesList;
    this.selectedItem = data.JobTitleNum;

    //Assign Group/Application list
    this.pGroups = ko.observableArray(data.GroupList);

    this.sections = ko.observableArray([{}]);

    this.ext = ko.observable(data.Ext);
    this.userId = ko.observable(data.UserId);
    this.olduserid = ko.observable(data.UserId);
    $("#ddbDepartments").val(data.DeptId);
    this.oldsectionid = ko.observable(data.SectionId);
    $("#ddbDepartments").change();
    this.oldsectionid = ko.observable(data.SectionId);
    //$("#SectionsDDB").val(data.SectionId);
};

var wrapper = function () {
    this.user = new userModel(userdata);
    this.sections = new sectionsModel(sectiondata);
};

var viewModel = new wrapper();
    ko.applyBindings(viewModel);

The pGroups HTML which is failing on the second attempt is: 第二次尝试失败的pGroups HTML是:

 <div data-bind="with: user" id="ActionWindow">

<form action="@Url.Action("SaveUserDetails", "AJAXUser")" method="post" class="AjaxSubmit" id="userDetailsForm">
    <h2>User: <span data-bind="text: fullName"></span></h2>
    <table>
        <tr>
            <td>First Name:</td>
            <td><input  type="text" name="FirstName" id="FirstName" data-bind="value: firstName" /></td>
            <td>
                <input type="hidden" name="UserNum" id="UserNum" data-bind="value: usernum" />
                <input type="hidden" name="OldUserId" id="OldUserId" data-bind="value: olduserid" />
                <input type="hidden" name="OldSectionId" id="OldSectionId" data-bind="value: oldsectionid" />
            </td>
            <td></td>
        </tr>

        <tr>
            <td>Surname:</td>
            <td><input type="text" name="Surname" id="Surname" data-bind="value: surname" /></td>
            <td></td>
            <td></td>
        </tr>

        <tr>
            <td>Job Title:</td>
            <td><select name="JobTitleNum" id="TitlesList" data-bind="options: jobTitles, optionsValue: 'TitleId', optionsText: 'Title', value: selectedItem"></select></td>
            <td></td>
            <td></td>
        </tr>

        <tr>
            <td>Extension:</td>
            <td><input type="text" name="Ext" id="Ext" data-bind="value: ext" /></td>
            <td></td>
            <td></td>
        </tr>

        <tr>
            <td>Login ID:</td>
            <td><input type="text" name="UserId" id="UserId" data-bind="value: userId" /></td>
            <td></td>
            <td></td>
        </tr>

        <tr>
            <td>Department:</td>
            <td>
                <select id="ddbDepartments" name="DeptId">
                    @foreach (var d in Model.DepartmentList)
                    {
                        <option value="@d.DeptId">@d.DeptName</option>
                    }
                </select>
            </td>
            <td>Section: </td>
            <td>
                <select name="SectionId" class="SectionsDDB" data-bind="options: $root.sections.list, optionsValue: 'SectId', optionsText: 'SectName', value: SectionId"></select>
                @*<select name="SectionId" class="SectionsDDB" data-bind="options: sections, optionsValue: 'SectId', optionsText: 'SectName', value: selectedItem"></select>*@
            </td>
        </tr>
    </table>
    <input type="submit" value="Update User" />
    <br />
</form>

<h2>Current Groups</h2>
<table>
    <tbody data-bind="foreach: pGroups">
        <tr>
            <td data-bind="text:AppName"></td>
            <td data-bind="text:GroupName"></td>
        </tr>
    </tbody>
</table>

Everything else is working. 其他一切都在工作。

I did find this: http://knockoutjs.com/documentation/plugins-mapping.html 我确实找到了这个: http : //knockoutjs.com/documentation/plugins-mapping.html

WHich indicates I should be mapping like this: 表示我应该像这样映射:

var viewModel = ko.mapping.fromJS(data, mapping);

but try as I might I cannot figure out how to apply this to my code. 但是请尽我所能,我无法弄清楚如何将其应用于我的代码。

Any help woud be greatly appreciated. 任何帮助将不胜感激。

Based on the link i provided in the previous comment( http://www.knockmeout.net/2012/05/quick-tip-skip-binding.html ) i made an example of your possible view model: 基于我在之前的评论中提供的链接( http://www.knockmeout.net/2012/05/quick-tip-skip-binding.html ),我举了一个可能的视图模型示例:

//the overall model
var wrapper = function () {
    this.user = ko.observable();
    this.user(new userModel(userdata));
    this.sections = new sectionsModel(sectiondata);
};
var viewModel = new wrapper();
ko.applyBindings(viewModel);

And then in the success of $('.ListUserLink').click you can have: 然后成功执行$('。ListUserLink')。click,您可以:

viewModel.user(new UserViewModel(data));

And in the success of $("#ddbDepartments").change you can have: 成功执行$(“#ddbDepartments”)。change,您可以:

viewModel.sections.sectionList(data.SectionList);

In the view, you can use the with binding along with $root to bind a nested view model: 在视图中,可以将with绑定与$ root一起使用以绑定嵌套视图模型:

  <div data-bind="with: user">
        <h2>User: <span data-bind="text: fullName"></span></h2>
        ...
      <select name="SectionId" class="SectionsDDB" data-bind="options: $root.sections.sectionList, optionsValue: 'SectId', optionsText: 'SectName', value: $root.sections.selectedValue"></select>
        ...
    </div>

As i understand, the sections are loaded based on the department selection. 据我了解,这些部分是根据部门选择来加载的。 So why don't you just add the sectionList observableArray to the UserViewModel and just add a subscription to the department id, so everytime the department changes, the list of sections is loaded: 那么,为什么不只将sectionList observableArray添加到UserViewModel并仅添加对部门ID的订阅,那么每次部门更改时,都将加载部分列表:

this.DeptId = ko.observable(data.DeptId);
this.sectionList = ko.observableArray(GetSections(this.DeptId()));
this.DeptId.subscribe(function () {
              var newSections =  GetSections(this.DeptId());
              this.sectionList(newSections);
            }, this);

GetSections function should call you GetSectionsByDept method. GetSections函数应调用您的GetSectionsByDept方法。 In your jsfiddle, if you comment the follwing lines, the data will load: 在您的jsfiddle中,如果注释以下几行,则数据将加载:

$("#ddbDepartments").val(data.DeptId);
$("#ddbDepartments").change();
$("#SectionsDDB").val(data.SectionId);

You should also replace the dropdownlist department with this: 您还应该使用以下命令替换下拉列表部门:

<select name="DeptId" id="ddbDepartments" data-bind="options: DepartmentList, optionsValue: 'Id', optionsText: 'DeptName', value: DeptId"></select>

But make sure to have an array of departments objects with Id/DeptName properties. 但是,请确保具有ID / DeptName属性的部门对象数组。

You doesn't need instance a new ViewModel always you have ajax server response. 您始终不需要ajax服务器响应,就不需要实例新的ViewModel。 You can apply bindings when page is ready and update data changes when ajax is finished or you can just remove the viewmodel bindings and apply again in your ajax. 您可以在页面准备就绪时应用绑定,而在ajax完成时更新数据更改,也可以只删除viewmodel绑定并再次在ajax中应用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM