【问题标题】:KnockoutJS proper way to update observableArray AJAXKnockoutJS 更新 observableArray AJAX 的正确方法
【发布时间】:2012-04-04 05:28:00
【问题描述】:

在 KnockoutJS 中,每次运行 AJAX 命令时更新 JSON 数据 observableArray 的正确方法是什么?

现在,我正在使用 viewmodel.items([]) 之类的东西来清空数组,然后用来自服务器的 JSON 数据重新填充它。没有使用 KnockoutJS 映射插件(这可能是唯一的方法)正确的路径是什么?

我的服务器逻辑每次都会发送一些相同的数据,所以我不能只是迭代并将项目推送到数组中,除非我想要重复。

//// 添加我今天的做法 ////

我不确定我为什么要这样做,但这正是我最初想出如何更新的方式。所以基本上,就像我之前说的,我得到 JSON 数据,然后我把它传递给这样的东西:

    _model.addIncident = function (json) {
       var checked = json.UserTouches > 0 ? true : false;
       _model.incidents.push({
          id: ko.observable(json.IncidentIDString),
          lastTouchId: ko.observable(json.UserLastTouchIDString),
          weight: ko.observable(json.Weight),
          title: ko.observable(json.Title),
          checked: ko.observable(checked),
          createdOn: ko.observable(json.IncidentCreatedOn),
          servicename: ko.observable(json.Servicename),
          inEdit: ko.observable(false),
          incidentHistory: ko.observableArray(),
          matchScore: ko.observable()
      });
   };

对于 JSON 数组中的每个节点。正如你所看到的,我在那里有一些自定义的可观察对象,它们会随着每条传递的数据而构建。也许这是错误的做法,但到​​目前为止效果很好。

【问题讨论】:

    标签: ajax json knockout.js knockout-mapping-plugin


    【解决方案1】:

    observableArray 实际上只是一个普通的 observable,它带有一些用于数组操作的额外方法。

    所以,如果你想将 observableArray 的值设置为一个新数组,你可以这样做:

    viewModel.items(myNewArray)

    映射插件可以帮助您使用任何更新来更新数组中的现有项目。在这种情况下,您的 UI 只会根据任何差异进行更新。

    【讨论】:

    • 所以,我在上面添加了一个我目前正在做的例子。基本上我正在为我的 JSON 中的每个项目构建一个自定义数组。如果我要这样做,那么按照您的建议将新数组直接泵入 observable,Knockout 会知道忽略重复项吗?也许这是一个糟糕的结构?感谢您的快速响应...我很想知道您如何处理这样的更新。我已经浏览了 Knockout 网站,但我从来没有真正注意到一个简单的解决方案......但这可能只是我的错 :)
    • 如果您使用foreach 绑定(或templateforeach 参数),那么UI 将适当更新。它将正确处理重复项,但请记住,旧项目 { name: 'Bob' } 不等于新项目 { name: 'Bob' },除非它们实际上是对同一项目的引用。这就是映射插件及其key 功能非常有用的地方,可以获取更新的数据并将其应用于现有对象。映射插件使这很容易。根据您上面所做的,映射插件可能是您的不错选择。
    • 我看到的映射插件的唯一问题是它会破坏我当前的整个视图模型,而不是动态创建的视图模型。您可以使用映射插件将 JSON 数据映射到我现有模型中的 observableArray 吗?我正在研究映射插件,我认为你是对的,它似乎确实是前进的方式,我只是还不熟悉它。
    • 我想一个更合乎逻辑的例子是我的 ViewModel 中有一个 UI 功能......类似于 viewModel.somethingClicked = function(){}。显然我把它放在这里是为了利用模板“点击”绑定,但据我了解,映射插件需要我将这个逻辑移到淘汰赛之外,因为它不是我的 JSON 数据模型的一部分。跨度>
    • 您可以使用映射插件来更新部分视图模型。类似:ko.mapping.fromJSON(newArrayAsJson, null, viewModel.items)。您可以将其用于使用映射插件初始化的数组,例如:viewModel.items = ko.mapping.fromJS([]);
    【解决方案2】:

    我知道我在这个问题上已经太晚了,因为我最近才发现自己陷入了这种情况。我们可以使用一个简单的 Javascript util 函数作为解决方法。

    如果您已经将_model.incidents标记为observableArray,则在绑定返回的JSON数据时可以这样做:

    eval("_model.incidents("+JSON.stringify(json)+");");
    

    它对我有用。希望你已经像这样创建了你的 observable:

    _model.incidents = ko.observableArray([]);
    

    【讨论】:

    • 因依赖 eval 而被否决。这看起来像一些奇怪的巫毒。为什么不简单地_model.incidents(json);
    猜你喜欢
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-18
    • 2013-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多