2015-03-11 9 views
6

Naprawdę mam nadzieję, że ktoś może mi pomóc z problemem, który miałem kilka razy ostatnio.Oceń ciąg w notacji kropkowej, aby uzyskać odpowiednią wartość z obiektu w widoku.

Załóżmy, że mam dwa obiekty w AngularJS.

$scope.fields = ['info.name', 'info.category', 'rate.health'] 

$scope.rows = [{ 
    info: { name: "Apple", category: "Fruit"}, 
    rate: { health: 100, ignored: true} 
},{ 
    info: { name: "Orange", category: "Fruit"}, 
    rate: { health: 100, ignored: true} 
},{ 
    info: { name: "Snickers", category: "Sweet"}, 
    rate: { health: 0, ignored: true} 
}] 

bym wtedy chciał wyświetlić tabelę w widoku, który pokazuje tylko pola w $scope.fields. Byłoby to bardzo proste, gdyby stół był płaski i wiem, że mogę go spłaszczyć za pomocą JavaScript, ale musi być sposób, aby to zrobić, przekształcając notację kropki na ścieżkę.

Dodałem JSFiddle wykazać problem mam:

JSFiddle: http://jsfiddle.net/7dyqw4ve/1/

Próbowałem również robić coś jak sugerował poniżej, ale problem jest jej straszna praktyką jest stosowanie funkcje w widoku: Convert JavaScript string in dot notation into an object reference

Jeśli ktoś ma jakieś pomysły, byłbym bardzo wdzięczny.

+0

Sugerowane podejście w połączonym pytaniu wydaje się być prawidłowe - czy nie można go po prostu zawinąć w filtrze? –

+1

Myślałem o tym również, ale (i przepraszam, jeśli jestem niepoprawny), z punktu widzenia wydajności, czy będziesz wysyłać cały zestaw danych do filtra wiele razy, zmniejszając prędkość, z której cały zestaw wierszy byłby biegać? Genuin question – Mark

+1

Dodatkowo powinieneś być bardzo ostrożny podczas korzystania z filtrów na DOM, szczególnie jeśli robi on ekstensywną operację, filtry działają tyle razy, ile potrzeba, aby ustabilizować się podczas jednego cyklu trawienia. Równie dobrze mógłbyś, gdyby kontroler odpowiednio ustawił model widoku w zakresie. – PSL

Odpowiedz

5

W tym przypadku można skorzystać z wbudowanego w kanciasty oceniającego narażone za pośrednictwem właściwości $eval sprawie zakresu (not the vanilla eval) ocena dowolnym kątem ekspresji (nie do oceny JavaScript jako eval robi). Angular wewnętrznie używa tego do oceny wyrażenia w zakresie podczas rozwiązywania powiązań.

Przykład: -

{{$eval(field, row)}} 

może zrobić: -

<th ng-repeat="field in fields">{{$eval(field, row)}}</th> 

lub owijać logiczny do sterowania i wystawiać je za pomocą metody z tego zakresu.

<th ng-repeat="field in fields">{{getValue(field, row)}}</th> 

i

$scope.getValue = function(exp, row){ 
    return $scope.$eval(exp, row); 
} 

Demo

Można także użyć $parse (wstrzyknąć $parse) usługi.

$scope.getValue = function(exp, row){ 
    return $parse(exp)(row); 
} 

i

<th ng-repeat="field in fields">{{getValue(field, row)}}</th> 

Demo

+0

Dzięki @PSL. Czy wiesz, czy to by było rozważane pod ** eval jest złe **? Czy jest to zła praktyka, czy akceptowalna w takich okolicznościach? – Mark

+2

@ Mark To nie jest "eval" – PSL

0

niewielkich zmian na PSL's answer który działa również:

<th ng-repeat="field in fields">{{$eval('row.'+field)}}</th> 

W $eval('row.'+field) pierwsze wyniki w row.info.name dla fields[0], na przykład. A następnie wiążące {{row.info.name}} powoduje Apple.

JSFiddle: http://jsfiddle.net/tbmpls/xhon86p7/8/

Ładny, prosty i zrozumiały, tak myślę.

To wydaje że wydajność powinna być grubsza odpowiada prostej {{row.info.name}} wiążącej, ponieważ tworząc ciąg powinien być niezwykle szybkie - ale zainteresowany czyichkolwiek komentarzach dotyczących tego produktu.

(Btw, to działa również wewnątrz NG-repeat gdzie lista jest zagnieżdżony w obiekcie jak:

<span ng-repeat="val in $eval('myobj.'+myPathInDotNotation) track by $index"> 

ale tak jak wszystko NG-repeat, to na pewno warto sprawdzić działanie w tej sprawie)

Powiązane problemy