【问题标题】:mapping json array to ko throwing error将 json 数组映射到 ko 抛出错误
【发布时间】:2013-09-30 20:00:59
【问题描述】:

我是 knockoutjs 的新手。我试图将json数据映射到ko。这是我的代码。

我想解析json数据并显示在表格中。当我尝试 ko.compute 它抛出我 self.firstName() 不是一个函数。当我尝试在计算函数之前在控制台中记录 firstName 的值时,它会在 json 数组中打印 3 个值并运行第四次并抛出一个错误,说 self.firstName 不是函数。

编辑:当我删除计算并仅打印 json 中的数据时,它能够正确映射。当我使用计算时出现问题。 当我在计算之前和映射之后尝试 console.log(self.firstName() ) 时,它会打印 jsonarray 中的值,但不是解析 3 次,而是解析 4 次和第 4 次,它给了我“不是函数”错误强>

<div id="employeeList">
 <table border ="2">
  <thead>
   <tr>
<th> First Name</th>
<th> Last Name</th>
<th> Age</th>
<th> Phone</th>
<th> Email</th>
</tr>
</thead>
<tbody  data-bind="foreach:employees">
<tr>
 <td data-bind="text:name"></td>
<td data-bind="text:firstName"></td>
<td data-bind="text:lastName"></td>
<td data-bind="text:age"></td>
<td data-bind="text:phone"></td>
<td data-bind="text:email"></td>
</tr>
</tbody>
</table>

</div>

这是我的js代码

     var personMapping={
          'copy':['age'],
          'employees': {
              create: function(options) {
                return new PersonViewModel(options.data);
            }
          }
     };


  function PersonViewModel(data){
      var self=this;
      ko.mapping.fromJS(data,personMapping,this);
       self.name=ko.computed(function(){
          return self.firstName()+' '+self.lastName();
      },this);


  }



var data={employees:
       [{
            firstName: 'Marco',
            lastName: 'Franssen',
            age: 26,
            phone: 12346789,
            email: "a@a.com"    
        },
        {
            firstName: 'Kumar',
            lastName: 'Rangarajan',
            age: 26,
            phone: 123467890,
            email: "a@b.com"
        },
        {
            firstName: 'A',
            lastName: 'B',
            age: 26,
            phone: 6775675567567,
            email: "a@c.com"}]
}

ko.applyBindings(new PersonViewModel(data), $('#employeeList'));


});

这是 jsfiddle 代码:http://jsfiddle.net/YfqPs/1/

【问题讨论】:

  • 您的视图模型是 PersonViewModel 您在 ko.applyBindings 中使用的,但在您的 personMapping 中您还使用了 PersonViewModel... 这是错字吗?你想用这个实现什么?某种递归映射?顺便说一句,您的小提琴无法正常工作 jquery 并且其中缺少映射插件...
  • console.log(this);PersonViewModel 内。我认为这可能是personMapping 这可能是您的问题。
  • 我想创建自己的映射。因此,我创建了人员映射,我不想将年龄作为可观察的,并创建了员工以映射到我在 foreach 中的员工。我看到这是可以做到的方法之一。
  • @Pricey :我不想为每个变量做一个可观​​察的。因此我尝试了映射。是的,当我将 firstName 创建为 observable 时,我在使用计算时没有问题。但我希望除了年龄之外的一切都是可观察的。而且我不知道如何在这种情况下进行映射。
  • @KumarR 是的,我把它从我的评论中去掉了,因为我忘了映射是为你做的。我建议您尝试 console.log(this); 虽然...请参阅 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 和关于对象方法。

标签: javascript jquery json knockout.js knockout-mapping-plugin


【解决方案1】:

您的代码被执行了 4 次,因为您将 PersonViewModel 重新用作您的主视图模型并在您的 personMapping 中使用您的视图模型:

  • 您的 PersonViewModel 被调用一次 3 个项目,因为此调用导致您的 employees 数组中的每个项目:

    create: function(options) {
       return new PersonViewModel(options.data);
    }
    
  • 您的PersonViewModel 在此呼叫的结果中被呼叫了 4 次:

    ko.applyBindings(new PersonViewModel(data), $('#employeeList'));
    

    这一次它引发了异常,因为您的主要 data 上没有 firstName 属性,只有您的员工。

有多种方法可以解决此问题,但所有方法都需要创建适当的独立“主”视图模型。

最简单的解决方案是使用var viewModel = ko.mapping.fromJS(data, personMapping); 创建您的“主”视图模型并在您的ko.applyBindings 中使用它:

var viewModel = ko.mapping.fromJS(data, personMapping);
ko.applyBindings(viewModel, $('#employeeList')[0]);

演示JSFiddle

【讨论】:

  • 感谢您的解决方案。你能告诉我是否有另一种方法可以在不创建主视图模型的情况下实现我想要实现的目标
  • 您不能为您的employeeList 和个别员工重复使用相同的函数PersonViewModel。您需要有两个视图模型才能使其工作。这是具有两个命名视图模型的替代解决方案:jsfiddle.net/nemesv/YfqPs/7 这是另一个解决方案,其中您的 PersonViewModel 是您的“主要”视图模型:jsfiddle.net/nemesv/J9r4K
【解决方案2】:

我正在努力让你的 jsfiddle 与相关的外部依赖项一起工作。所以现在我建议你不要使用映射或尝试这个旨在取代它的映射器 http://coderenaissance.github.io/knockout.viewmodel/

我期待的是您从 personMapping 对象的上下文中调用 create 函数,因为它是该对象的属性。

这意味着在下面的代码中,我会认为this 实际上是personMapping 而不是PersonViewModel,这意味着您的mapping.fromJS 正在尝试将personMapping 映射到自身。

var self=this;
ko.mapping.fromJS(data,personMapping,this);

【讨论】:

    【解决方案3】:

    在您的data 中,firstNameemployees 下。

    看起来你应该像这样拨打电话:

    return new PersonViewModel(options.data.employees);
    

    包含ko.computed 的视图模型应该接受单个员工并进行计算。

    function PersonViewModel(employee){
       var self=this;
       self.name=ko.computed(function(){
          return self.firstName()+' '+self.lastName();
      },this);
    }
    

    jsFiddle

    【讨论】:

    • 当我删除计算并只打印 json 中的数据时,它能够正确映射。当我使用计算时出现问题。
    • 问题是你的selfdata,它没有firstName作为它的属性。
    • 但是当我在计算之前打印 self.firstName() 时,它会正确打印 json 数组中的值。但是它进行了 4 次解析而不是 3 次,并且在第四次解析中它抛出了 not a function 错误
    猜你喜欢
    • 2017-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-24
    • 2019-09-18
    • 1970-01-01
    • 2015-02-03
    • 2014-05-31
    相关资源
    最近更新 更多