【问题标题】:Add object to collection将对象添加到集合
【发布时间】:2014-12-09 15:07:08
【问题描述】:

我有一个包含表单的单页 MVC 4 应用程序(称为 ParentForm)。有多个ChildForms 附加到ParentForm。单击按钮时,每个ChildForm 都会在模式对话框中弹出,如下所示:

我的 ASP.NET ViewModel 如下所示:

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>();
    }
}

我不知道如何制作一个代表这个的 Knockout.JS ViewModel。我的 ViewModel 目前看起来像这样:

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)? Knockout.JS collection example 并不能帮助我弄清楚如何将字符串以外的任何内容添加到 ParentForm 的集合中。我希望 ChildForms 包含在 ParentForm ViewModel 的列表中。

【问题讨论】:

  • 父表单是否需要有多个个“A”实例?
  • @Jeroen 是的。特别是,我对调用 ko.applyBindings 时发生的事情有很多困惑;什么样的事物要推入ParentFormViewModel.AddChildFormA. 例如,每次提交有效的ChildForm 时为ChildFormA 创建一个新的ViewModel 并对其执行ko.applyBindings 的策略是什么? ?

标签: knockout.js


【解决方案1】:

最简单的方法是使用 jQuery $.map 函数将每个项目映射到新对象 o ChildFormA 或 ChildFormB。这在教程中进行了演示:http://learn.knockoutjs.com/#/?tutorial=loadingsaving

没有必要创建 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}));
}

http://jsfiddle.net/tfdeLs7u/

【讨论】:

  • 我同意你回答的本质。尽管有一些额外的解释会更好,特别是一些事情。你应该说一下为什么你有 childrenAchildrenB outside 父级(这与 OP 的服务器端模型一致,但与他的客户端模型不一致)。其次,OP 将它们作为observableArrays,而您将它们作为普通属性。也许您可以添加一个解释,说明您为什么选择普通属性,和/或有什么区别?最后,OP 在AddChildFormA 表示了一些麻烦,也许也可以添加解释?
  • @Jeroen 我以为我很清楚。鉴于问题中的信息有限,我试图给出最佳答案。我不确定为什么我需要解释为什么儿童模型应该在外面。他没有提供他的完整模型,但很明显他至少了解基本的 OO javascript。我确实对我为什么不使用 observableArrays 发表了评论。
  • @WayneEllery 谢谢,这有助于消除我的困惑。父表单与其子表单之间可能有 60 多个表单字段,如果不完全了解 KO.JS/MVVM 的起始原理,使用起来会很困难。 ko.applyBindings 在这里如何使用?每个包罗万象的 ViewModel 只有一次?
  • 是的,每个 ViewModel 一次
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多