2

我有一个带有剔除绑定的项目列表。简化它看起来像这样:

<ul data-bind="foreach: currentItems ">
    <li>
        <div>
            <span data-bind="text: Heading"></span>
        </div>
   </li>
</ul>

在选择列表中,我有可以添加到第一个列表的潜在项目。双击某个值时,将使用 selectedItem 启动 ajax 调用。

<select id="lstSongs" data-bind="options: possibleItems, optionsText: 'Heading', value: selectedItem, dblclick: $root.addItem"></select>

两个阵列都使用服务器上定义的相同模型结构。

视图模型如下所示:

function MyViewModel() {
    var self = this;
    self.currentItems = ko.observableArray([]);
    self.possibleItems = ko.observableArray([]);
    self.selectedItem = ko.observable();

    self.addItem = function(item) {
        $.ajax({
            type: "POST",
            url: "/api/MyController/AddItem",
            contentType: "application/json",
            dataType: "json",
            data: ko.toJSON(item),
            success: function(itemId) {

                // Attempt1
                alert(itemId);
                item.ItemId(itemId);
                alert("hello1");
                alert(item.ItemId);
                currentItems.push(item);

                // Attempt2
                alert(itemId);
                item.ItemId = itemId;
                alert("hello2");
                alert(item.ItemId);
                currentItems.push(item);

                // Attempt3
                alert(itemId);
                selectedItem.ItemId = itemId;
                alert("hello3");
                alert(selectedItem.ItemId);
                currentItems.push(selectedItem);
            }
        });
    };
}

var viewModel = new MyViewModel();
var data = @Html.Raw(new JavaScriptSerializer().Serialize(Model));
ko.mapping.fromJS(data, {}, viewModel);
ko.applyBindings(viewModel);

带有 currentItems 的列表是从带有 ko.mapping 的 MVC 初始模型加载的。possibleItems 加载了来自动态 ajax 调用的值。但两者都按预期加载,所以我认为这些绑定没问题。

双击按预期触发。在服务器上检测到调用并返回适当的 itemId。成功返回时,应在 selectedItem 上设置该值。然后 selectedItem 应该被添加到 currentItems 数组并出现在第一个列表中。

我已经详细阐述了几次尝试,但没有成功。我当时尝试了其中一个,其他人发表了评论。

Attempt1:返回 itemId 但未到达第一个 hello。为什么?这不是设置可观察属性的方法吗?

Attempt2:设置值,显示 hello2 并报告设置了 itemId。但是推送调用不会使该项目出现在 currentItem 列表中。

Attempt3:相同的方法,但这次属性是在 viewModel selectedItem 上设置的。这次没有到达 hello3。

4

4 回答 4

2

您的第一次尝试不起作用,因为item可能没有作为可观察值传递,而是作为值传递。

您的第二次尝试应该可以正常工作,但是您需要使用该self变量:

self.currentItems.push(item);

您的第三次尝试与第一次尝试的原因不同。

于 2013-08-27T00:56:46.127 回答
1

您必须创建添加项目的实例并将其分配给您 selectedItem 和 currentItems 数组相应

success: function() {    
    var addedItem = new Item {ItemId:item.ItemId,Heading:item.Heading };
    self.selectedItem(addedItem);
    self.currentItems.push(addedItem);
    alert("Successfully added");   
}
于 2013-08-26T22:56:56.883 回答
1

Bradley Trager 的第一个建议让我走上了正轨。为了帮助其他人,我只是在此处添加工作解决方案:

var addedItem = ko.mapping.fromJSON(ko.toJSON(item));
addedItem.ItemId(itemId);
self.currentItems.push(addedItem);
于 2013-08-27T21:17:50.687 回答
0

我想我可以重现你的问题。在我看来,您的问题是您正在对 的(双击)单击进行数据绑定select,而您希望在options上触发事件。alert(itemId)如果你不这样做,你可以看到这一点console.log(item):它是被传递给你的函数的根视图模型。

想到了两个解决方案:

  • 使用自定义绑定处理程序来查找实际单击的元素(在略读时类似于此方法);或者
  • 删除select并使用带有单独模板项目(“选项”)的列表,每个项目都有一个dblclick绑定。
于 2013-08-26T22:25:25.767 回答