1

在使用 Knockout 将视图模型中的父/子关系表示为视图中的单选按钮选择时,我遇到了一个奇怪的问题。

在下面的示例中,我有一个表示两个应用程序的视图模型。每个应用程序包含三个角色和一个选定的角色 ID。

在视图中,我将每个应用程序下的角色显示为单选按钮列表。应检查其值与父级的选定角色 ID 匹配的按钮。

<script src='knockout-2.0.0.js' type='text/javascript'></script>
<script src='knockout.mapping.js' type='text/javascript'></script>

<ul data-bind='template: { name: "applicationTemplate", foreach: Applications }'></ul>

<script type='text/html' id='applicationTemplate'>
  <li><span data-bind='text: Name'></li>
  <ul data-bind='template: { name: "roleTemplate", foreach: Roles }'></ul>      
</script>

<script type='text/html' id='roleTemplate'>
  <li>
    <input type='radio' data-bind='value: Id, 
      checked: $parent.SelectedRoleId(), 
      attr: { name: "roleFor" + $parent.Id(), id: "roleFor" + $parent.Id() + "_" + Id() }' />
    <label data-bind='text: Name, 
      attr: { for: "roleFor" + $parent.Id() + "_" + Id() }'></label>
  </li>        
</script>  

<script type='text/javascript' language='javascript'>

  var data = {
    'Applications': [
      { 'Id': 8, 'Name': 'Weather Predictor', 'SelectedRoleId': 1, 'Roles': [
          { 'Id': 1, 'Name': 'Meteorologist' },
          { 'Id': 2, 'Name': 'Farmer' },
          { 'Id': 3, 'Name': 'Pair of Dice' }               
        ]
      },
      { 'Id': 9, 'Name': 'Daily Crime Report', 'SelectedRoleId': 6, 'Roles': [
          { 'Id': 4, 'Name': 'Superhero' },
          { 'Id': 5, 'Name': 'Commissioner' },
          { 'Id': 6, 'Name': 'Journalist' }
        ]
      }
    ]       
  };

  var viewModel = ko.mapping.fromJS(data);

  ko.applyBindings(viewModel);

</script>

一开始一切都很好:

  • 天气预报员
    • [X] 气象学家
    • [ ] 农民
    • [ ] 一对骰子
  • 每日犯罪报告
    • [ ] 超级英雄
    • [ ] 专员
    • [X] 记者

但是当我点击“Farmer”时,“Weather Predictor”下的所有角色都未选中:

  • 天气预报员
    • [ ] 气象学家
    • [ ] 农民
    • [ ] 一对骰子
  • 每日犯罪报告
    • [ ] 超级英雄
    • [ ] 专员
    • [X] 记者

再次单击“Farmer”不仅会选中单选按钮,而且从那时起它将正常工作。只是第一次点击会出现问题。如果我也单击“一对骰子”或任何其他未选中的单选按钮,也会发生同样的问题。

这个问题困扰了我一段时间,我开始怀疑我是否在这里不正确地使用了 Knockout。

任何对此问题的见解将不胜感激!

4

2 回答 2

2

当您使用checked绑定时,您会希望避免使用value绑定,因为它会附加不必要的事件处理程序。

一个简单的选择是valueattr绑定中添加 (因此您只是设置 value 属性而不添加事件处理程序),然后将checked绑定放在它之后(因此在运行value之前已经设置了checked),例如:

data-bind='attr: { value: Id, name: "roleFor" + $parent.Id(), id: "roleFor" + $parent.Id() + "_" + Id() }, checked: $parent.SelectedRoleId'

示例:http: //jsfiddle.net/rniemeyer/Y478G/

于 2012-05-31T00:57:55.780 回答
0

代替

value: Id, checked: $parent.SelectedRoleId()

value: Id(), checked: $parent.SelectedRoleId

示例:http: //jsfiddle.net/nickolsky/zrBuL/10/

于 2012-05-31T00:49:49.907 回答