2013-01-15 13 views
11

że mamy zbiór projektów narażonych poprzez usługę projektu:Jak powiązać złożone obiekty z radiami i polami wyboru w AngularJS?

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

Następnie mamy formularz, aby wybrać swój ulubiony projekt:

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

Ustawia choices.favoriteProject wartości id wybranego projektu. Często musimy uzyskać dostęp do powiązanego obiektu, a nie tylko id:

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

Co szukam jest sposobem związania radia i wyboru prosto do samego obiektu, a nie identyfikator, więc mogliśmy zamiast tego można uzyskać

John's favorite project: 
{{data.favoriteProject.name}} 

. Jest to możliwe dzięki wybraniu dyrektywy za pomocą opcji ng, ale jak możemy to zrobić z radiami i polami wyboru? Nadal chciałbym użyć identyfikatorów do dopasowania zamiast referencji, jeśli to możliwe.

celu wyjaśnienia, oto przykład co szukam

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}} 

on mówi: „Proszę związać data.favoriteProject do rzeczywistego przedmiotu projektu i użyć identyfikatora, by sprawdzić, czy są one zgodne (zamiast referencji) ".

Odpowiedz

14

[Aktualizacja]

mam całkowicie zmieniło moją odpowiedź po odkryciu dyrektywę ngValue, który wydaje się być udokumentowany. Pozwala na wiązanie obiektów zamiast samych łańcuchów jako wartości dla ngModel na wejściach przycisków radiowych.

<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> 

ta wykorzystuje odniesienia do sprawdzenia raczej niż tylko identyfikatory, ale myślę, że w większości przypadków, jest to, co ludzie będą szukać. Jeśli chcesz ściśle dopasować tylko na podstawie identyfikatorów, możesz użyć [Old Answer], poniżej lub nawet lepiej, po prostu utwórz funkcję - np. projectById(projectId), którego można użyć do wyszukiwania projektu na podstawie jego identyfikatora.

I został uaktualniony JSFiddle wykazać: http://jsfiddle.net/BinaryMuse/pj2GR/


[Old Odpowiedź]

Być może można wykorzystać atrybut dyrektywy przycisk radiowy ng-change aby osiągnąć to, co chcesz. Rozważmy następujący kod 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> 

Można również wywołać funkcję wewnątrz ng-change np setfavoriteProject(project) --but ja tego nie zrobiłem tutaj dla uproszczenia.

Oto pracuje jsFiddle zademonstrować techniki: http://jsfiddle.net/BinaryMuse/pj2GR/7/

+0

Dziękujemy! Naprawdę podoba mi się to rozwiązanie. To proste, ale działa zgrabnie! Pozostawiam pytanie otwarte na inne rozwiązania na teraz. Problem polega na tym, że istnieje duplikacja danych (identyfikator) i musimy sami zarządzać ustawianiem wartości. – randomguy

+1

Dlaczego warto używać projektów [$ index] zamiast tylko obiektu projektu? – randomguy

+1

Dokonałem tego refaktoryzacji w jsFiddle, ale zapomniałem zaktualizować post. Dzięki! –

1

Nie ng-zmiana potrzebne (i nie jestem pewien, czy jest to dobra praktyka, aby napisać inline-kod jak to z drugiej strony. dyrektywy angulars nie są zbyt odległe od siebie).Dlaczego nie po prostu zrobić coś takiego (współpracuje z NG-repeat również):

Fiddle: http://jsfiddle.net/JohannesJo/VeZxh/3/

Kod:

<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 = {}; 
}); 

Edit: I może powinienem wspomnieć, że to nie działa dla pól wyboru, jako wartość będzie albo prawda, albo fałsz. Również wspólny model spowoduje, że wszystkie pola wyboru będą zaznaczone lub odznaczone w tym samym czasie.

+0

Patrz rozwiązanie "ng-value", jest dość elastyczne – genuinefafa

Powiązane problemy