jquery 对话框中不断添加淘汰赛数据

knockout data keep adding on the jquery dialog

我对敲除和 jquery 对话框有疑问。问题是我在超链接上打开对话框。问题是每次关闭和打开对话框时,我都会得到重复数据。每当我关闭和打开对话框时,数据都会一次又一次地附加。我尝试在对话框关闭时销毁对话框,但问题仍然存在。

我在下面的代码中做了什么

1) 我正在打开一个带有对话框的 div。在对话框的打开事件中,我正在从服务器获取数据。

2) 我正在使用 knockout 视图模型来存储和持久化数据。

问题是什么

每当我打开和关闭时,每次点击超链接都会出现重复的行 dialog.The 问题不会出现在第一页上 load.The 问题只会在进一步点击超链接时出现。

 <div id="divforjobactivity" class="hidden">
    <h5 class="title1" style="padding-left: 500px">
        Job Activity Form</h5>
    <table id="gvActivityForm" class="test">
        <thead>
        <tr> <td> <div id="divstatus"></div> </td></tr>
        <tr>
            <th class="thdata">
             Y1
            </th>
 <th class="thdata">
             Y2
            </th>

            </tr>
        </thead>

        <tbody data-bind="foreach: arraytoadd">

                    <tr>

                         <td data-bind="text: y1"></td>

                        <td data-bind="text: y2"></td>



    </table>



</div>
 $(document).on("click", "[id*=hypJobActivity]", function () {

      var $tr = $(this).closest('tr');  // gets closest parent tr element to the anchor element
      var x1 = $(".x1", $(this).closest("tr")).html()
      var $addJobActivityContainer = $("#divforjobactivity"); 
      TemplateFunction = function () {

        var self = this;
        self.y2 =ko.observable(0);
        self.y1 = ko.observable(0);        
    }
    // set the view model for 
      JobActivity = function () {

        var self = this;
        self.errors = ko.observableArray();
        self.arraytoadd = ko.observableArray();
        self.addevent = function () {

            self.arraytoadd.push(new TemplateFunction());
        }
    }      

    jobactivityVM = new JobActivity();
    ko.cleanNode($addJobActivityContainer[0]);
    ko.applyBindings(jobactivityVM, $addJobActivityContainer[0]);
    obj = {};        
    obj.x1 = x1;       
    $("#divforjobactivity").dialog({ height: 320,width: 1230,modal: true,

 open:function   (event,ui)         
            $.ajax({     //start ajax call for posting and getting the data back
                type: 'POST',
                url: 'PopupWebService.asmx/ReceiveandSendJobActivity',
                data: JSON.stringify({ item: obj }),
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (response) {                      

                    for (var i = 0; i < response.d.length; i++) {

                        var x = new TemplateFunction();
                        x.y1(response.d[i].Y1); 
                        x.y2=((response.d[i].Y2);                                       
                        jobactivityVM.arraytoadd.push(x);
                    }                  

                }, //end of sucess att

                close: function (event, ui) {

                    $("#divforjobactivity").dialog("destroy");
                    $("#divforjobactivity").remove();
                }, // end of close 

                error: function (XMLHttpRequest, textStatus, errorThrown) {
                alert("Unable to retrieve requested information " + errorThrown);

                }     //end of error

            }); //END OF DIALOG

我认为问题纯粹是您在添加新条目之前没有清除以前的条目。您应该在添加新数组之前清除 arraytoadd 数组:

success: function (response) {
    //call the observableArray function with an empty array to clear it             
    jobactivityVM.arraytoadd([]);

    for (var i = 0; i < response.d.length; i++) {
        var x = new TemplateFunction();
        x.y1(response.d[i].Y1); 
        x.y2=((response.d[i].Y2);                                       
        jobactivityVM.arraytoadd.push(x);
    }                  
}, //end of sucess att

当您关闭对话框时,您并没有清除 jobactivityVM observableArray。因此,下次打开对话框时,您将调用 AJAX 并将更多项目添加到数组中。

要么在关闭对话框时清除 jobactivityVM,要么在ajax成功

时重置内容
close: function (event, ui) {
    $("#divforjobactivity").dialog("destroy");
    $("#divforjobactivity").remove();
    jobactivityVM.removeAll();
}

success: function (response) {
    var newItems = response.d.map( function(item) {
        var x = new TemplateFunction();
        x.y1 = item.Y1;
        x.y2 = item.Y2;
        return x;
    });
    jobactivityVM.arraytoadd( newItems );

我更喜欢第二种方法,因为当在 observableArray 上调用 push 时,所有依赖项也会更新。在您的情况下, DOM 会在循环的每次迭代中刷新(即添加新的 table 行)。对于 2 个元素不是那么重要,对于 100 个元素将是重要的。还要注意 map 函数的使用 - IE9+。您仍然可以将 for 循环与单个 DOM 更新一起使用,但代码有点难看

success: function (response) {
    var underlyingArray = jobactivityVM.arraytoadd();
    for(var i = 0; i < response.d.length; i++) {
        var x = new TemplateFunction();
        x.y1 = response.d[i].Y1;
        x.y2 = response.d[i].Y2;
        underlyingArray.push(x);   // Add directly to the real array, Knockout won't detect the change and fire any DOM updates
    });
    // Now tell Knockout to fire any subscriptions
    jobactivityVM.arraytoadd.notifySubscribers( jobactivityVM.arraytoadd() );

@Robert Stanley 和@James Thorpe,感谢您的帮助。我尝试了您的解决方案 @Robert,我尝试了您解决方案的一部分,@james 我尝试了您的解决方案。问题是我必须从超链接单击事件中取消应用绑定。多重绑定导致了问题。

$(document).ready(function () 

// 我已经更改了将代码从单击事件放置到文档就绪的逻辑,因为如果我只是打开和关闭对话框并且我正在使用 appply 绑定,我的 dom 不会刷新点击事件。

{

 var $addJobActivityContainer = $("#divforjobactivity"); 
var $addJobActivityContainer = $("#divforjobactivity"); 
  TemplateFunction = function () {

    var self = this;
    self.y2 =ko.observable(0);
    self.y1 = ko.observable(0);        
}
// set the view model for 
  JobActivity = function () {

    var self = this;
    self.errors = ko.observableArray();
    self.arraytoadd = ko.observableArray();
    self.addevent = function () {

        self.arraytoadd.push(new TemplateFunction());
    }
}      

jobactivityVM = new JobActivity();
ko.cleanNode($addJobActivityContainer[0]);
ko.applyBindings(jobactivityVM, $addJobActivityContainer[0]);





$(document).on("click", "[id*=hypJobActivity]", function () {


  var $tr = $(this).closest('tr');  // gets closest parent tr element to the anchor element
  var x1 = $(".x1", $(this).closest("tr")).html()

   obj = {};        
   obj.x1 = x1;    


$("#divforjobactivity").dialog({ height: 320,width: 1230,modal: true,

打开:函数(事件,ui)
$.ajax({ //开始 ajax 调用发送和取回数据 类型:'POST', url: 'PopupWebService.asmx/ReceiveandSendJobActivity', 数据:JSON.stringify({ item: obj }), 内容类型:"application/json; charset=utf-8", 数据类型:"json", 成功:函数(响应){

                for (var i = 0; i < response.d.length; i++) {

                    var x = new TemplateFunction();
                    x.y1(response.d[i].Y1); 
                    x.y2=((response.d[i].Y2);                                       
                    jobactivityVM.arraytoadd.push(x);
                }                  

            }, //end of sucess att

            close: function (event, ui) {

                $("#divforjobactivity").dialog("destroy");
                $("#divforjobactivity").remove();
            }, // end of close 

            error: function (XMLHttpRequest, textStatus, errorThrown) {
            alert("Unable to retrieve requested information " + errorThrown);

            }     //end of error

        }); //END OF DIALOG


       }); //end of document.ready