【问题标题】:Knockout - Having trouble accessing nested JSON data淘汰赛 - 访问嵌套 JSON 数据时遇到问题
【发布时间】:2015-10-07 09:47:10
【问题描述】:

关于在 Knockout 中访问嵌套 JSON 有几个类似的问题,但我无法让它工作。我确定这很简单。如果可能的话,我想在没有 knockout.mapping 插件的情况下执行此操作。

编辑:

这是我整理的小提琴。 https://jsfiddle.net/ym0h4w49/14/

我无法像在我正在处理的网站上那样实际渲染 dom,但 console.log 显示了 singleContact 对象。取消注释 self.tags 以查看它是如何中断的。

鉴于这个带有嵌套对象的 JSON 响应:

{
  "id": 1,
  "firstname": "Ina",
  "lastname": "Church",
  ... etc ...
  "registered": "2014-10-06T11:22:51 +05:00",
  "tags": [
    {
      "id": "t1",
      "contactId": 1,
      "tagLabel": "wguldin"
    }
  ]
}

我如何访问此人的tags?我尝试了以下方法。

function detailViewModel(contactID) {
  var self = this;
  self.contactID = ko.observable(contactID);
  self.contact = ko.observableArray([]);

  self.getContact = function(id) {
      $.ajax({
        type: 'GET',
        url: 'http://localhost:3000/contacts/' + id + '?_embed=tags&_embed=reminders',
        dataType: 'json',
        success: function(data) {
          var contactData = new singleContact(data);
          self.contact(contactData);
        }
      });
  }

  self.getContact(self.contactID());
};

这个视图模型创建了一个新的singleContact,它像这样处理数据:

function singleContact(data) {
  var self = this;

  self.firstName = data.firstname;
  self.lastName = data.lastname;
  ...

  self.tags = ko.observableArray(ko.utils.arrayMap(self.tags, function(tag) {
      return new tag(tag.id, tag.contactID, tag.tagLabel);
  }));
};

我认为应该将标签信息传递给这个函数。

function tag(id, contactID, tagLabel) {
    var self = this;

    self.id = id;
    self.contactID = contactID;
    self.tagLabel = tagLabel;
}

但是当我 console.log singleContact 时,一个奇怪的函数东西出现为tags 值。

我不确定这是否意味着它存在,但它不会使用此标记在 DOM 中呈现:

<!-- ko foreach: contact -->
  <h1 data-bind="text: firstName"></h1>

  ...

  <!-- ko foreach: tags -->
  <p data-bind="text: tag.tagLabel"></p>
  <!-- /ko -->

<!-- /ko -->

谢谢!

【问题讨论】:

  • 如果您可以解决问题,这将有助于您快速解决问题,
  • 它并不完美,但我添加了一个。谢谢!

标签: javascript jquery json knockout.js


【解决方案1】:

试试这样的

查看:

<!-- ko foreach: contact -->
  <h1 data-bind="text: firstName"></h1>
  <!-- ko foreach: tags -->
  <p data-bind="text:tagLabel"></p>
  <!-- /ko -->
<!-- /ko -->

视图模型:

var json = {
  "id": 1,
  "firstname": "Ina",
  "lastname": "Church",
  "registered": "2014-10-06T11:22:51 +05:00",
  "tags": [
    {
      "id": "t1",
      "contactId": 1,
      "tagLabel": "wguldin"
    }
  ]
}

function tag(id, contactID, tagLabel) {
    var self = this;
    self.id = id;
    self.contactID = contactID;
    self.tagLabel = tagLabel;
}

function singleContact(data) {
  var self = this;
  self.firstName = data.firstname;
  self.lastName = data.lastname;
    var con =  ko.utils.arrayMap(data.tags, function(item) { // use item rather tag which may give different meaning & loop through data.tags 
      return new tag(item.id, item.contactID, item.tagLabel);
  });
  self.tags = ko.observableArray(con); 
};

function detailViewModel() {
  var self = this;
  self.contact = ko.observableArray([]);
  self.contact([new singleContact(json)]); // use [] here to make it array
};
ko.applyBindings(new detailViewModel())

样例工作摆弄here

在这里查看您的工作fiddle sample

【讨论】:

  • 所以,这适用于标签!但是,我的数据还有第二个子对象。我试着编辑你的小提琴来说明。我认为它只适用于第二个,我错过了什么吗? jsfiddle.net/LkqTU/25385
  • 一个错字兄弟! .你正在循环通过reminder 而不是reminders。在这里查看jsfiddle.net/LkqTU/25398。欢呼
  • 天哪,这不是第一次发生在这个项目上。你超级酷。感谢您的帮助!
【解决方案2】:

我认为这很好,我认为您需要做的就是更改淘汰赛绑定

<!-- ko foreach: contact -->
  <h1 data-bind="text: firstName"></h1>

  ...

  <!-- ko foreach: tags() -->
  <p data-bind="text: tag().tagLabel"></p>
  <!-- /ko -->

<!-- /ko -->

【讨论】:

  • 那没有任何效果......对不起!
  • 在你的控制台日志中你能看吗,但是在它后面加上()看看里面有什么数据
猜你喜欢
  • 2015-06-02
  • 2014-12-11
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
  • 1970-01-01
  • 2013-10-08
  • 2012-09-05
  • 1970-01-01
相关资源
最近更新 更多