【问题标题】:Knockout.js - Trying to add JSON to viewmodel is undefinedKnockout.js - 尝试将 JSON 添加到 viewmodel 是未定义的
【发布时间】:2015-10-06 15:29:33
【问题描述】:

我已经看到了几个问题,但我仍然无法弄清楚我在这里做错了什么。

我想要做的是从服务器获取一个 JSON 对象,如下所示:

{
  "firstname": "Blanchard",
  "lastname": "Buckner",
  ...
}

视图模型执行 AJAX 调用,并且数据似乎设置正确。但是当我尝试将它传递给我的 singleContact 函数以绑定到视图时,什么也没有发生。

我是 Knockout 的新手,所以我确信我犯了一个非常容易的错误,但我已经尝试了一段时间来解决这个问题,但没有任何效果。

// Binds json db data to each contact.
function singleContact(data) {
  var self = this;

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

  self.fullName = ko.computed(function() {
      return self.firstName + " " + self.lastName;    
  }, self);

  self.image = data.image;
  self.position = data.position;
  self.company = data.company;
};

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,
      dataType: 'json',
      success: function(data) {
        console.log(singleContact(data)); <---- Always Undefined. The data is a JSON object.
      }
    });
  }

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

编辑: 这是标记,第一次应该包含它。

<!-- ko foreach: contact -->
  <img class="contact__image" data-bind="attr:{src: image, alt: fullName}" />
  <h1 data-bind="text: fullName"></h1>
  <h2>
    <span data-bind="text: position"></span>,
    <span data-bind="text: company"></span>
  </h2>

  <h5>Notes on <span data-bind="text: fullName"></span></h5>
  <p></p>
<!-- /ko -->

【问题讨论】:

  • 您能否也发布您的标记,以便我查看您的绑定是如何指定的?
  • 安德鲁,它已被添加。感谢您的观看!

标签: javascript json knockout.js knockout-3.0


【解决方案1】:

您需要使用new 关键字来创建singleContact 对象:

var contact = new singleContact(data);

然后可以将其分配给 detailViewModel 上的 observable:

self.singlecontact(contact);

我还建议您对 viewModel 使用 Upper Camelcase。 IE。 DetailViewModel 而不是 detailViewModel,就像在使用面向对象编程时使用任何其他语言一样。

【讨论】:

  • @AndrewMount。本教程不使用这种大小写:learn.knockoutjs.com/#/?tutorial=loadingsaving。我也找不到这个外壳的文档。 knockoutjs.com/documentation/computedObservables.html。对象应该是驼色的。用于新对象的函数应该是大写驼峰式。我在编辑之前回答了。视图不存在。
  • 很公平,在他们的 observables 文档中,他们的视图模型是骆驼案例,但我确实看到他们在提供的链接中混合并使用了上骆驼。我也没有意识到你没有看到标记。我将删除我的评论。
  • @AndrewMount 请解释混合的意思。视图模型函数为大写驼峰式,视图模型为驼峰式。
  • 如果你看这里:knockoutjs.com/documentation/observables.html 他们使用小骆驼,因为他们实际上并没有构建实例。我连忙看了一眼,把脚放在嘴巴的地方。
  • @AndrewMount 在那个文档中它们只是视图模型,所以它们是驼峰式的。如果函数用于 ViewModel 类型,则函数名称将是大写的驼峰式
【解决方案2】:

这是一个工作示例。缺少的是您没有将创建的模型推入 observableArray。我已经证明您可以取回一系列结果并轻松推送。

function DetailViewModel(id) {
  var self = this;
  self.contacts = ko.observableArray([]);

  // make ajax call.. mocking here
  var results = ajax();

  results.forEach(function(result) {
    self.contacts.push(new Contact(result));
  });
}

function Contact(data) {
  var self = this;
  self.firstName = data.firstName;
  self.lastName = data.lastName;
  self.company = data.company;
  self.position = data.position;
  self.image = data.image;

  self.fullName = ko.pureComputed(function() {
    return self.firstName + ' ' + self.lastName;
  });

  return self;
}

function ajax() {
  return [{
    firstName: 'Rich',
    lastName: 'Hickey',
    company: 'Cognitect',
    position: 'CTO',
    image: 'http://gotocon.com/dl/photos/speakers/Rich%20Hickey2.jpg'
  }, {
    firstName: 'Scott',
    lastName: 'Hanselman',
    company: 'Microsoft',
    position: 'Architect',
    image: 'http://www.globalnerdy.com/wordpress/wp-content/uploads/2009/09/scott_hanselman.jpg'
  }];
}

$(function() {
  ko.applyBindings(new DetailViewModel());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<!-- ko foreach: contacts -->
<div>
  <img class="contact__image" data-bind="attr:{src: image, alt: fullName}" style="width: 100px; height: 150px" />
  <h1 data-bind="text: fullName"></h1>
  <h2>
    <span data-bind="text: position"></span>,
    <span data-bind="text: company"></span>
  </h2>

  <h5>Notes on <span data-bind="text: fullName"></span></h5>

</div>
<!-- /ko -->

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-07
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-02
    • 1970-01-01
    相关资源
    最近更新 更多