【问题标题】:How to remove items from external observableArray with KnockoutJS如何使用 KnockoutJS 从外部 observableArray 中删除项目
【发布时间】:2013-07-09 20:40:50
【问题描述】:

目标

使用 KnockoutJS 从外部 observableArray 中删除项目。

问题

我的应用程序中有两个observableArray。一种是可供购买的产品,另一种是我通过单击add button 在摘要中添加的产品。

到这里为止,一切正常。但现在我需要从 Summary 中删除项目并更改按钮状态/样式 - 我不知道如何访问外部 observableArray 来执行此操作。

要了解我的问题,请查看this jsFiddle 或查看下一个主题中的标记。

如您所见,当我单击add button 时,产品会转到摘要。当我单击删除时——无论按钮是来自摘要还是产品——我都想更改按钮状态并从摘要中删除该项目。从技术上讲,我想使用products' observableArrayitems' observableArray 中删除该项目。

我的代码

HTML:

<ul class="summary">
    <!-- ko foreach: Summary.items -->
        <p data-bind="text: name"></p>
        <button class="btn btn-danger btn-mini remove-item">
            <i class="icon-remove">×</i>
        </button>
    <!-- /ko -->
</ul>

<h1>What would you to buy?</h1>

<ul class="products">
    <!-- ko foreach: Product.products -->
    <li>
        <h3 data-bind="text: name"></h3>
        <p data-bind="text: desc"></p>
        <!-- ko if:isAdded -->
        <button data-bind="if: isAdded" class="btn btn-small btn-success action remove">
            <i data-bind="click: $root.Summary.remove" class="icon-ok">Remove</i>
        </button>
        <!-- /ko -->
        <!-- ko ifnot:isAdded -->
        <form data-bind="submit: function() { $root.Summary.add($data); }">
            <button data-bind="ifnot: isAdded" class="btn btn-small action add">
                <i class="icon-plus">Add</i>
            </button>
        </form>
        <!-- /ko -->
    </li>
    <!-- /ko -->
</ul>

JavaScript:

function Product(id, name, desc) {
    var self = this;

    self.id = ko.observable(id);
    self.name = ko.observable(name);
    self.desc = ko.observable(desc);
    self.isAdded = ko.observable(false);
}

function Item(id, name) {
    var self = this;

    self.id = ko.observable(id);
    self.name = ko.observable(name);
}

function SummaryViewModel() {
    var self = this;
    self.items = ko.observableArray([]);

    self.add = function (item) {
        self.items.push(new Item(item.id(), item.name()));

        console.log(item);

        item.isAdded(true);
    };

    self.remove = function (item) {
        item.isAdded(false);
    };
};

function ProductViewModel(products) {
    var self = this;

    self.products = ko.observableArray(products);
};

var products = [
    new Product(1, "GTA V", "by Rockstar"), 
    new Product(2, "Watch_Dogs", "by Ubisoft")
];

ViewModel = {
    Summary: new SummaryViewModel(),
    Product: new ProductViewModel(products)
}

ko.applyBindings(ViewModel);

【问题讨论】:

  • 请从您的代码中添加一些可用的 sn-ps 到您的问题中,以防万一您的 jsfiddle 链接在未来失效并且这个问题变得不可读。
  • 感谢您的提示,尼尔。我做到了。

标签: javascript knockout.js


【解决方案1】:

你可以search for it

您可以在购物车中查询具有相同 id 的商品,然后将其删除

self.remove = function (item) {
    var inItems = self.items().filter(function(elem){
        return elem.id() === item.id(); // find the item with the same id
    })[0];
    self.items.remove(inItems);
    item.isAdded(false);
};

除非您有数十万个项目,否则这应该足够快。只要记住使用items.remove(),它就会知道更新observableArray :)

【讨论】:

  • 哦,谢谢本杰明。但是,如果我点击摘要项目上的“x”?
  • @GuilhermeOderdenge 您没有向其添加操作:) 您应该在答案中使用相同的技术向其添加处理程序。不过,我可能会以不同的方式处理设计 - 有一个 observableArray 的产品和两个 computed 函数用于选择在哪里显示。这样你就不需要明确地管理它,你只需要设置 isAdded 就可以了,这在逻辑上是最有意义的。
  • Benjamin,您能否详细介绍一下“用于选择在哪里显示的两个计算函数”?或者,也许是一个例子?你的观点很好,很高兴听到它。
  • @GuilhermeOderdenge StackOverflow 不是“免费为我编写此代码”网站。虽然我喜欢回答有关设计、如何构建代码或如何完成一般事情的问题——比如你最初的问题是关于如何在 KnockoutJS 的另一个集合中找到项目,但我无意解决应用程序错误不是问题,我也不打算编写您的生产代码。这不是本网站的工作方式,这将教会其他面临同样问题的用户什么都没有,而且在教学上通常是一种糟糕的方法。
  • @Sarcastic 因为这就是 OP 的代码所做的。他的项目具有hisAdded 属性。您断言删除逻辑不需要它是正确的。
【解决方案2】:

一旦您将 products 声明为 observableArray,您应该可以对其调用 remove(根据 this)。假设您有对要删除的对象的引用以传入。

【讨论】:

    猜你喜欢
    • 2013-10-23
    • 2012-07-12
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    • 2017-10-22
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    相关资源
    最近更新 更多