Как привязать к сложным объектам с помощью радиостанций и флажков в AngularJS?
Скажем, у нас есть набор проектов, открытых через службу проекта:
{ 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}}
Это устанавливает для параметра choice.favoriteProject значение id выбранного проекта. Часто нам нужно получить доступ к связанному объекту, а не только к id:
John favorite project:
{{Project.get(data.favoriteProject).name}}
Я ищу способ привязать радиостанции и флажки прямо к самому объекту, а не к id, поэтому мы могли бы сделать
John favorite project:
{{data.favoriteProject.name}}
вместо этого. Это возможно с помощью директивы select с помощью ng-опций, но как мы можем это сделать с помощью радиостанций и флажков? Я по-прежнему хотел бы использовать идентификаторы для сопоставления вместо ссылок, если это возможно.
Чтобы пояснить, вот пример того, что я ищу
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 к реальному объекту проекта и используйте идентификатор, чтобы проверить, соответствуют ли они (вместо ссылок)".
Ответы
Ответ 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>
Это использует ссылки для проверки, а не только идентификаторы, но я думаю, что в большинстве случаев это то, что люди будут искать. Если вы очень строго соглашаетесь только на соответствие идентификаторам, вы можете использовать [Старый ответ] ниже или даже лучше, просто создайте функцию - например. projectById(projectId)
, который вы можете использовать для поиска проекта на основе его идентификатора.
Я обновил 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/
Ответ 2
Нет необходимости в ng-изменении (и я не уверен, если это хорошая практика для написания встроенного кода, подобного этому. С другой стороны, директивы углов не слишком далеки от этого). Почему бы просто не сделать что-то подобное (работает также с 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. Кроме того, общая модель приведет к тому, что все флажки будут проверяться или не отмечены одновременно.