Knockout.js 将对象添加到集合

Knockout.js 将对象添加到集合,knockout.js,Knockout.js,我有一个单页MVC4应用程序,其中包含一个表单(称之为ParentForm)。有多个子表单附加到父表单。单击按钮时,每个子窗体都会在模式对话框中弹出,如下所示: 我的ASP.NET视图模型如下所示: public class ParentFormViewModel { public ParentForm parent { get; set; } public IEnumerable<ChildFormA> childrenA { get; set; } pu

我有一个单页MVC4应用程序,其中包含一个表单(称之为
ParentForm
)。有多个
子表单
附加到
父表单
。单击按钮时,每个子窗体都会在模式对话框中弹出,如下所示:

我的ASP.NET视图模型如下所示:

public class ParentFormViewModel
{
    public ParentForm parent { get; set; }
    public IEnumerable<ChildFormA> childrenA { get; set; }
    public IEnumerable<ChildFormB> childrenB { get; set; }

    public GeneralFormViewModel()
    {
        parent = new ParentForm ();
        childrenA = new List<ChildFormA>();
        childrenB = new List<ChildFormB>();
    }
}
function ParentFormViewModel(dozens of parameters) {

    var self = this;

    self.property = new ko.observable(property);
    // dozens of these...

    self.childrenA = ko.observableArray(ChildFormA);
    self.childrenB = ko.observableArray(ChildFormB);

    self.AddChildFormA = function () {
        self.childrenA.push(???);
    }

    var viewModel = new ParentFormViewModel();
    ko.applyBindings(viewModel);

如何创建“子窗体”(例如,
ChildFormB
)的实例并将其添加到“父窗体”的子窗体集合(例如,
ParentForm.childrenA
)中?除了向父窗体的集合中添加字符串之外,该函数无法帮助我了解如何添加其他内容。我希望
ChildForm
s包含在
ParentForm
ViewModel的列表中。

最简单的方法是使用jQuery
$.map
函数将每个项映射到ChildFormA或ChildFormB的新对象。本教程对此进行了演示:

无需使childrenA和childrenB成为可观察的数组,因为看起来这些数据总是来自服务器,而且看起来您不会动态地将子元素添加到此数组中。如果您正在动态添加子项,并且需要更新屏幕,则将其声明为observableArrays

self.parent = new ParentForm(model.parent);
self.childrenA = $.map(model.childrenA, function(item) { return new ChildFormA(item) });
self.childrenB = $.map(model.childrenB, function(item) { return new ChildFormB(item) });

var ParentForm = function (parentForm) {
    var self = this;
    self.name = ko.observable(parentForm.name);
    self.age = ko.observable(parentForm.age);
};
在这里,我还添加了ChildFormA和ChildFormB,它们是为来自服务器的子数组中的每个项实例化的

var ChildFormA = function (childFormA) {
    var self = this;
    self.name = ko.observable(childFormA.name);
    self.age = ko.observable(childFormA.age);
};

var ChildFormB = function (childFormB) {
    var self = this;
    self.name = ko.observable(childFormB.name);
    self.cost = ko.observable(childFormB.cost);
};
如果您确实想使用self.AddChildFormA函数等函数添加另一个子项,则需要推送一个新的ChildFormA实例

self.AddChildFormA = function () {
    self.childrenA.push(new ChildFormA({name: 'Lucy', age: 24}));
}

父窗体是否需要多个“A”实例?@Jeroen是的。特别是,我对调用
ko.applyBindings
时发生的事情有很多困惑;例如,每次提交有效的
ChildForm
时,为
ChildFormA
创建一个新的视图模型,并对其执行
ko.applyBindings
的策略是什么。不过最好再加上一些解释,特别是一些事情。你应该说说为什么你在父母之外有
childrenA
childrenB
(这与OP的服务器端模型一致,但与他的客户端模型不一致)。其次,OP将它们作为
observableArray
s,而您将它们作为普通属性。也许您可以添加一个解释,解释为什么选择普通属性,和/或区别是什么?最后,OP在
AddChildFormA
中指出了一些问题,也许还添加了解释?@Jeroen我想我已经很清楚了。鉴于问题中的信息有限,我试图给出最佳答案。我真的不知道为什么我需要解释为什么儿童模特应该在外面。他没有提供完整的模型,但很明显,他至少了解基本的OOJavaScript。我确实对我为什么不使用observableArrays发表了评论。@WayneEllery谢谢,这有助于澄清我的困惑。在父窗体和它的子窗体之间可能有60多个窗体字段,如果不完全理解KO.JS/MVVM的起始原则,就很难使用这些字段。这里如何使用
ko.applyBindings
?每个包罗万象的ViewModel只有一次?是的,每个ViewModel只有一次