如何在ajax调用后删除Knockout.js ObservableArray-object

时间:2016-09-19 10:43:32

标签: ajax knockout.js

我试图在ajax调用之后从ObservableArray中删除一个对象。它适用于' .pop'功能,但不是在我使用自定义knockout.js' .remove' -function时。

如果我将通话转移到'。删除'在ajax-complete函数之外的函数,' .remove'确实有效。但我真的宁愿把它放在' .complete'。

有人能发现我做错了吗?

这不起作用:

self.removeItem = function(data){

    $.ajax({
        type: 'POST',
        url:'/echo/js/?js=hello%20world!',
        dataType: 'json',
        contentType: 'application/json',
        data: null
    }).complete(function (item,data)  {
             self.Items.remove(data);
    });
};

我做了一个jsfiddle演示:http://jsfiddle.net/6oe6dn7n/1/

我的视图模型如下:

var data = {
  Name: "Test",
  Items: ["One", "Two", "Three"]    
};

function ViewModel(data) {
  var self = this;
   self.Items = ko.observableArray(ko.utils.arrayMap(data.Items,   

function(item) {
    return { value: ko.observable(item) };
}));

self.removeItem = function(data) { 

    $.ajax({
        type: 'POST',
        url:'/echo/js/?js=hello%20world!',
        dataType: 'json',
        contentType: 'application/json',
        data: null
    }).complete(function (item,data)  {
             // This doesn't affect the observableArray.
             // 'self.Items.pop(data) does, however.
             self.Items.remove(data);
    });
};
}

我的HTML看起来像这样:

<div>
    <table>
        <tbody data-bind="template: { name: 'itemTemplate', foreach: Items     }"></tbody>
    </table>
</div>
<script type="text/html" id="itemTemplate">
    <tr>
        <td>
            <input data-bind="value: value" />
            <a href="#" data-bind="click: $parent.removeItem">Remove     Item</a>
        </td>
    </tr>
</script>

2 个答案:

答案 0 :(得分:2)

您已更换&#34;数据&#34;响应处理程序上下文中的变量对象:

是:

self.removeItem = function(data) { // <- data
    $.ajax({
        type: 'POST',
        url:'/echo/js/?js=hello%20world!',
        dataType: 'json',
        contentType: 'application/json',
        data: null
    }).complete(function (item, data)  { // <- another data overrides upper data
             // This doesn't affect the observableArray.
             // 'self.Items.pop(data) does, however.
             self.Items.remove(data); // <- what data to use???
    });
};

改变:

self.removeItem = function(data) { 
    $.ajax({
        type: 'POST',
        url:'/echo/js/?js=hello%20world!',
        dataType: 'json',
        contentType: 'application/json',
        data: null
    }).complete(function (item, data1)  { // another data - data1
             // This doesn't affect the observableArray.
             // 'self.Items.pop(data) does, however.
             self.Items.remove(data);
    });
};

我已更新了fiddle,它对我有用 - 至少会移除项目。

答案 1 :(得分:1)

您需要使用传递给removeItem的数据变量。而是通过使用完整回调的textStatus变量来覆盖它。像这样:

self.removeItem = function(data) { 
    $.ajax({
        type: 'POST',
        url:'/echo/js/?js=hello%20world!',
        dataType: 'json',
        contentType: 'application/json',
        data: null
    }).complete(function (item)  {
             self.Items.remove(data);
    });
};

self.Items.pop(data)工作的原因是因为.pop实际上并没有采用任何参数。因此,您传入的数据永远不会被使用,并且调用只是弹出数组。完整回调方法中的第二个参数默认为textStatus响应。

从文档中: http://api.jquery.com/jQuery.ajax/

  

<强>完整   类型:函数(jqXHR jqXHR,String textStatus)   请求完成时要调用的函数(执行成功和错误回调之后)。该函数传递了两个参数:jqXHR(在jQuery 1.4.x,XMLHTTPRequest中)对象和一个对请求状态进行分类的字符串(&#34;成功&#34;,&#34; notmodified&#34;,&#34 ; nocontent&#34;,&#34;错误&#34;,&#34;超时&#34;,&#34; abort&#34;或&#34; parsererror&#34;)。