1

我最近开始使用 Knockout,大多数事情都非常容易。然而,这个让我有点难过,希望有人能提供一些帮助。我正在通过序列化具有 Master/Detail 结构的 JSON 对象来创建我的 Knockout 模型,我怀疑这会导致我的一些问题。我可以绑定/呈现记录的主部分,并且可以使用 foreach 模板绑定和呈现详细信息。但是,在我的场景中,我希望用户从子列表中选择要编辑的详细记录。问题是我无法让选择起作用。我正在触发 click 事件,并且似乎我的详细记录正在传递给我的事件 - 除了我无法读取属性的值。在提琴手看来,通过的对象是事件的函数调用。目前还不确定。所以,这是我的设置

我的 JSON

{
"Height":"250",
"Width":"200",
"Speed":"700",
"Pause":"4",
"ShowItems":"1",
"Animation":"fade",
"MousePause":"true",
"IsPaused":"false",
"Direction":"up",
"DataItems":[{
     "OrderId":1,
     "ItemHtml":"This is item 1"
  },{
     "OrderId":2,
     "ItemHtml":"This is item 2"
  },{"
     OrderId":3,
    "ItemHtml":"This is item 3"
  }]
}

用于序列化 JSON 对象的 Javascript

var viewModel = {
  vmRotator: ko.mapping.fromJSON(jsonObj)

  //-- THIS IS WHERE I THINK THE PROBLEM IS
  , selectRotatorItem: function (item) {
    //alert(item.OrderId); // THIS DOES NOT WORK
    console.log(item);
  }
}
ko.applyBindings(viewModel);

//-- hookup the click event for templated items
$("#rotatorItems").on("click", ".sel", function () {
  var data = ko.dataFor(this);
  viewModel.selectRotatorItem(data); //-- call to object function
});     

用于显示项目的 HTML,提供单击按钮

<table id="rotatorList" width="100%" border="0" cellspacing="0" cellpadding="2">
  <tbody id="rotatorItems" data-bind="template: { foreach: vmRotator.DataItems }">
  <tr>
    <td style="width: 20px;">
      <input type="button" class="sel" value="Select" />
      <span data-bind="text: OrderId"></span>
    </td>
    <td style="width: 90%;" data-bind="text: ItemHtml"></td>
  </tr>
  </tbody>
</table>

最好我能说这一切正常。我的事件正在被调用,但是当我在控制台中查看结果时,它看起来像是函数的文本而不是值。

在函数中:

, selectRotatorItem: function (item) {
  //alert(item.OrderId); // THIS DOES NOT WORK
  console.log(item);
}

alert(item.OrderId) 显示:

"function d(){if(0<arguments.length){if(!d.equalityComparer||!d.equalityComparer(c,arguments[0]))d.H(),c=arguments[0],d.G();return this}b.r.Wa(d);return c}"

而不是像 1 或 2 这样的数字,它是 Order ID 的值。不知道为什么会这样,但我做错了什么。

我通过查看几个与我正在做的类似的示例将这段代码拼凑在一起。我可能会以完全错误的方式解决这个问题,但我认为我只是缺少一些简单的东西。我敢肯定,那里的一些 Javasctipt 神可以很容易地看到我看不到的东西,所以我很感激你的帮助。


为了回应符文对我最初问题的回答,这是有效的最终版本

用于构建绑定的 Javascript 代码

//-- define models: master and detail modesl
var viewRotatorItemModel = {
  'Height': ko.observable(),
  'Width': ko.observable()
};

var viewRotatorModel = {
  'Height': ko.observable(),
  'Width': ko.observable(),
  'Speed': ko.observable(),
  'ShowItems': ko.observable(),
  'Animation': ko.observable(),
  'IsPaused': ko.observable(),
  'Direction': ko.observable(),
  'UseEditor': ko.observable(),
  'HtmlData': ko.observable(),
  'DataItems': {
        create: function (options) {
        return new viewRotatorDataItem(options.data);
      }
    }
};

//-- define objects around models
var viewRotatorDataItem = function (data) {
  var self = this;
  //--> IMPORTANT TO USE fromJS as JSON is already an object
  ko.mapping.fromJS(data, viewRotatorItemModel, self); 
  self.selectItem = function () {
    alert("item with id " + self.OrderId() + " clicked");
  };
};

var ViewModel = function (data) {
    var self = this;
    //--> IMPORTANT TO USE fromJSON as incoming object is JSON text
    ko.mapping.fromJSON(data, viewRotatorModel, self);
};

...
...

//-- create objects when ready
    vmRotator = new ViewModel(jsonObj);
    ko.applyBindings(vmRotator);    

用于显示主/明细项目的 HTML

<h4>Main Items</h4>
<input type="text" id="wc_Height" data-bind="value: vmRotator.Height" />

<input type="text" id="wc_Width" data-bind="value: vmRotator.Width" />

<h3>Detail Items</h3>
<table id="rotatorList" width="100%" border="0" cellspacing="0" cellpadding="2">
  <tbody id="rotatorItems" data-bind="template: { foreach: vmRotator.DataItems }">
  <tr>
    <td style="width: 20px;"> 
      <input type="button" value="Select" data-bind="click: selectItem" />
      <span data-bind="text: OrderId"></span>
    </td>
    <td style="width: 90%;" data-bind="text: ItemHtml"></td>
  </tr>
</tbody>
</table>
4

2 回答 2

1
于 2013-04-07T05:07:47.977 回答
0

我认为问题是您应该删除#rotatorItems 的jQuery 绑定,并在.sel 按钮上使用'click' 绑定:

请看这个小提琴:

http://jsfiddle.net/EKXKF/2/

主要变化:

<tbody id="rotatorItems" data-bind="foreach: vmRotator.DataItems">
  <tr>
    <td style="width: 20px;">
      <input type="button" class="sel" value="Select" data-bind="click: $root.selectRotatorItem" />
      <span data-bind="text: OrderId"></span>
    </td>
    <td style="width: 90%;" data-bind="text: ItemHtml"></td>
  </tr>
</tbody>
于 2013-04-07T05:35:10.263 回答