如何从子模型调用父方法(淘汰赛)

时间:2014-11-17 13:32:00

标签: knockout.js

我认为标题极具误导性,但问题很简单。

好的,让我对此进行透视 - fiddler

我有三种型号:BoardViewModel,List,Card

好吧,长话短说,list模型会创建一个名为cards的数组 self.cards = ko.observableArray(cards);(第79行)

Knockout反过来将myObservableArray.remove()作为ko.observableArray()的一部分公开。

这反过来又允许我放弃那些符合其目的的卡片 self.cards.remove(card);(第99行)

问:我有什么方法可以从card型号调用remove()吗?
或者我是否需要在List模型中定义另一个函数并传递card对象,以便能够拨打与第99行相同的调用?
self.archive = function (card)(第68行)

提示:点击编辑链接/按钮,找到存档按钮

4 个答案:

答案 0 :(得分:3)

其他答案很好,但似乎你是以一种令人困惑的方式解决问题。将卡作为类的整个想法是,它需要对包含它的数组一无所知(如果它包含在数组中)。

在视图中处理此问题的首选方法是,如果您的卡上有“删除”按钮,则在视图中将其写入:

<div data-bind="foreach: cards">
    <div class="card">
    <div class="content"> ... </div>
    <button data-bind="click: $parent.cards.remove">Remove</button>
  </div>
</div>

这样,您可以将卡片类与其容器分开,可以在此特定视图中以优雅的方式处理从其容器中移除卡片。

答案 1 :(得分:1)

createCard对象上展开List方法,以处理Card中所有List个对象的创建:

self.createCard = function (id, title, description, contentItemId) {
    if (id) {
        self.cards.push(new Card(id, title, description, contentItemId, self.cards));
    } else {
        var title = $('#textTitle').val().trim();
        if (title.length > 0) {
            var newCard = new Card(-1, title, "", -1, self.cards);
            self.cards.push(newCard);
            // clear data
            $('#textTitle').val('');
        }
    }
}

请注意,它会将对observableArray的{​​{1}}的引用推送到Card对象中。然后,卡片对象可以保持这一点并使用它:

Card

但是,当您将父var Card = function(id, title, description, contentItemId, list) { var self = this; this.containingArray = ko.observable(list); /*...*/ self.archive = function (card) { self.containingArray.remove(self); }; } 从一个列表拖到另一个列表时,您需要更新此属性。您可以为绑定添加另一个选项来执行此操作:

List

<div class="cards" data-bind="sortable: { data: cards, afterMove: cardMoved }"> 模型中使用相应的功能

List

答案 2 :(得分:1)

我的解决方案与James有点类似,但我更喜欢将回调传递给对象,而不是整个父列表; (我会以不同的方式处理卡片构造)

所以卡构造函数看起来像

var Card = function (id, title, description, contentItemId, removeCallback) {
    //Rest unchanged
    self.archive = function () {
        removeCallback(self);
    };
}

然后,您的列表将如下所示:(请注意从cardscardData的更改)

var List = function (id, name, cardData, sortOrder) {
    var self = this;

    function removeCard(card) {
        self.removeCard(card);
    }

    self.cards = ko.observableArray(cardData.map(function (data) {
        //Construct a card object from the provided data
        return new Card(data.id, data.title, data.description, data.contentItemId, removeCard);
    }));
    //Rest unchanged
}

最后,在构建列表时,您需要更改

中的每张卡片
new Card(1, "Document all code", "Document all classes, methods and properties in source code.", -1),

{
    id: 1,
    name: "Document all code",
    description: "Document all classes, methods and properties in source code.",
    contentItemId: -1
}

JSFiddle

答案 3 :(得分:0)

您可以将父List的引用添加到卡中(构造函数中的额外参数),然后:

self.archive = function () {
    self.parentList.removeCard(self);
};

JSFiddle

您还需要处理父级更改,例如@James说。