如何在 AngularJS 中使用收音机和复选框绑定到复杂对象?

Posted

技术标签:

【中文标题】如何在 AngularJS 中使用收音机和复选框绑定到复杂对象?【英文标题】:How to bind to complex objects with radios and checkboxes in AngularJS? 【发布时间】:2012-12-29 14:16:24 【问题描述】:

假设我们有一组通过项目服务公开的项目:

 id: '123', name: 'Yeoman', watchers: '1233', ... 
 id: '123', name: 'Grunt', watchers: '4343', ... 

然后,我们有一个表格来选择你最喜欢的项目:

Select favorite project:
%label.radio(ng-repeat="project in Project.query()")
  %input(type="radio" ng-model="data.favoriteProject" value="project.id") project.name

这会将choices.favoriteProject 设置为所选项目的id 值。通常,我们需要访问相关对象,而不仅仅是 id:

John's favorite project:
Project.get(data.favoriteProject).name

我正在寻找一种将单选框和复选框直接绑定到对象本身而不是 id 的方法,因此我们可以这样做

John's favorite project:
data.favoriteProject.name

相反。这可以通过 ng-options 使用 select 指令来实现,但是我们如何使用收音机和复选框来做到这一点?如果可能的话,我仍然想使用 id 进行匹配而不是引用。

为了澄清,这是我正在寻找的示例

Select favorite project:
%label.radio(ng-repeat="project in Project.query()")
  %input(type="radio" ng-model="data.favoriteProject" value="project" ng-match="id") project.name

它说:“请将 data.favoriteProject 绑定到实际的项目对象并使用 id 检查它们是否匹配(而不是引用)”。

【问题讨论】:

【参考方案1】:

[更新]

在发现 ngValue 指令后,我完全改变了我的答案,该指令似乎没有记录。它允许您在单选按钮输入上绑定对象而不仅仅是字符串作为ngModel 的值。

<label ng-repeat="project in projects">
  <input type="radio" ng-model="data.favoriteProject"
    ng-value="project">project.name</input>
</label>

<p>Your favorite project is data.favoriteProject.name.</p>

这使用引用来检查,而不仅仅是 ID,但我认为在大多数情况下,这就是人们会寻找的。如果您确实非常严格地只想根据 ID 进行匹配,您可以使用下面的 [Old Answer],甚至更好,只需创建一个函数 - 例如projectById(projectId) 可用于根据项目 ID 查找项目。

我已经更新了 JSFiddle 来演示:http://jsfiddle.net/BinaryMuse/pj2GR/


[旧答案]

也许您可以利用单选按钮指令的ng-change 属性来实现您想要的。考虑这个 html

<p>Select your favorite project:</p>
<label ng-repeat="project in projects">
  <input type="radio" ng-model="data.favoriteProjectId" value="project.id"
         ng-change="data.favoriteProject = project">
    project.name
  </input>
</label>

<p>Your favorite project is data.favoriteProject.name.</p>

您也可以在ng-change 中调用一个函数,例如setfavoriteProject(project)——但为了简单起见,我没有在这里这样做。

这是一个演示该技术的工作 jsFiddle:http://jsfiddle.net/BinaryMuse/pj2GR/7/

【讨论】:

谢谢!我真的很喜欢这个解决方案。这很简单,但它工作得很好!我暂时将这个问题留给其他解决方案。这样做的问题是存在重复的数据(id),我们必须自己管理设置值。 为什么使用项目[$index] 而不仅仅是项目对象? 我在 jsFiddle 中进行了重构,但忘记更新帖子。谢谢! 这种方法的复选框有一个小问题。 ng-change 在选中和取消选中时触发,因此即使我们取消选中,也会设置 favouriteProject。 有趣的是,ng-model 在这里或多或少是被抛弃的。【参考方案2】:

不需要 ng-change (而且我不确定,编写这样的内联代码是否是一种好习惯。另一方面,角度指令本身并不太远)。为什么不直接做这样的事情(也适用于 ng-repeat):

小提琴: http://jsfiddle.net/JohannesJo/VeZxh/3/

代码:

<body ng-app="app">
<div ng-controller='controller'>
<input type = "radio" ng-model = "oSelected"  value = "aData[0]">
<input type = "radio" ng-model = "oSelected"  value = "aData[1]">
<div>test:     oSelected</div>
</div>
</body>


app = angular.module('app',[]);

app.controller('controller', function($scope)
$scope.aData = [
    o:1,
    o:2
];
$scope.oSelected = ;
);

编辑:我可能应该提到这不适用于复选框,因为值将是真或假。此外,共享模型将导致所有复选框同时被选中或取消选中。

【讨论】:

ng-value 解决方案,它非常灵活

以上是关于如何在 AngularJS 中使用收音机和复选框绑定到复杂对象?的主要内容,如果未能解决你的问题,请参考以下文章

Jquery - 如何删除复选框和收音机上的多个味精返回

如何通过在 AngularJS 中绑定来捕获来自无效属性的 html 编译错误

无法摆脱收音机和复选框中的 Firefox 焦点显示

如何在任何 div 中选择下拉菜单?

html Evan Lovely的CodePen。自定义复选框和收音机表单元素 - 使用CSS3使复选框和收音机看起来很漂亮:)

当元素为(显示:无)时如何显示选中的收音机元素