问题 如何使用AngularJS中的无线电和复选框绑定到复杂对象?


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

{ 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来检查它们是否匹配(而不是引用)”。


4037
2018-01-15 13:08


起源



答案:


[更新]

发现后我完全改变了我的回答 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匹配,你可以使用 [旧答案],下面,甚至更好,只需创建一个功能 - 例如。 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/


14
2018-01-16 06:20



谢谢!我非常喜欢这个解决方案。它很简单,但它工作得很整齐!我现在将问题留给其他解决方案。这个问题是数据重复(id),我们必须自己管理设置值。 - randomguy
为什么使用项目[$ index]而不仅仅是项目对象? - randomguy
我在jsFiddle中进行了重构,但忘了更新帖子。谢谢! - Michelle Tilley
使用此方法的复选框存在轻微问题。 ng-change on on check并取消选中,这样即使我们取消选中,也会设置favoriteProject。 - randomguy
有趣的是,ng模型在这里或多或少都是扔掉了。 - Dogweather


答案:


[更新]

发现后我完全改变了我的回答 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匹配,你可以使用 [旧答案],下面,甚至更好,只需创建一个功能 - 例如。 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/


14
2018-01-16 06:20



谢谢!我非常喜欢这个解决方案。它很简单,但它工作得很整齐!我现在将问题留给其他解决方案。这个问题是数据重复(id),我们必须自己管理设置值。 - randomguy
为什么使用项目[$ index]而不仅仅是项目对象? - randomguy
我在jsFiddle中进行了重构,但忘了更新帖子。谢谢! - Michelle Tilley
使用此方法的复选框存在轻微问题。 ng-change on on check并取消选中,这样即使我们取消选中,也会设置favoriteProject。 - randomguy
有趣的是,ng模型在这里或多或少都是扔掉了。 - Dogweather


不需要更改ng(我不确定,如果编写这样的内联代码是一个好习惯。另一方面,angulars指令与它们自己并不太远)。为什么不做这样的事情(也适用于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 = {};
});

编辑:我可能应该提到这对复选框不起作用,因为值将为true或false。此外,共享模型将导致所有复选框同时被选中或取消选中。


1
2018-02-28 21:08



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