2015-11-16 13 views
5

Mam wyjście JSON z items - Aby wyświetlić pojedynczy element, używam ng-repeat="item in items". I mogę uzyskać dostęp do aktualnie zalogowanego obiektu użytkownika z userng-if indexOf z JSON Array

Każdy przedmiot może należeć do wielu życzeń użytkowników. Jeśli użytkownik dodaje element do jego życzeń user_id zostaje zapisany w ciągu item.wishlists

Wyjście JSON pojedynczego item wygląda uproszczony coś takiego:

{"id":1,"title":"This is a tile","wishlists":[{"user_id":2},{"user_id":3}]} 

kiedy robię user.id dostaję ID bieżącego zalogowany użytkownik.

Teraz chcę użyć w ramach w ramach ng-repeat="item in items", aby sprawdzić, czy bieżący użytkownik dodał już tę pozycję do swojej listy życzeń, a następnie wyświetlić temu użytkownikowi przycisk "usuń z listy życzeń" zamiast "dodaj do listy życzeń".

moje podejście nie działa to:

<div ng-repeat="item in items"> 
    <h3>{{item.title}}</h3> 
    <a href="" ng-click="addToWishlist(item)" ng-if="item.wishlists.indexOf(user.id) == -1">Wish</a> 
    <a href="" ng-click="removeFromWishlist(item)" ng-if="item.wishlists.indexOf(user.id) > -1">Undo-Wish</a> 
</div> 

mogę używać indexOf jak to? Lub jaki byłby prawidłowy sposób AngularJS, aby sprawdzić, czy user.id jest w item.wishlists user_id's?

Update:

Widok: (ctrl.hasWished zmienia ikonę z 'ulubionym' jeżeli prawdziwe 'favorite_border' jeśli fałsz)

<div ng-repeat="item in items"> 
     <md-button class="md-icon-button feed-wish md-warn" aria-label="Wish" ng-click="ctrl.toggleWish(item)"> 
     <i class="material-icons">favorite{{ctrl.hasWished(item) ? '' : '_border' }}</i> 
     </md-button> 
</div> 

Kontroler:

// Check if User has wished this item already: Should return true or false 
    this.hasWished = function(item) { 
    return item.wishlists.some(function(wishlist) { 
     return wishlist.user_id === Auth._currentUser.id; // returns true if currently logged in user id is on wishlist 
    }); 
    }; 

    this.toggleWish = function(item) { 
    if (!this.hasWished) { 
     this.hasWished = true; 
     items.wish(item); // sends PUT request 
     ToastService.show(item.product + ' added to Wish List'); 
    } else { 
     this.hasWished = false; 
     items.unWish(item); // sends DELETE request 
     ToastService.show(item.product + ' removed from Wish List'); 
    } 
    } 

Kiedy klikam na przycisk, jeśli jest on fałszywy wcześniej, wysyła żądanie PUT, a także otrzymuję ToastSer vice message "added ..", jeśli kliknę ponownie, wysyła żądanie DELETE, a wiadomość ToastService "remove ..". Ale ikona nie zmienia się z "ulubionego" na "ulubiony_przycisk". Po ponownym załadowaniu strony wyświetlane są odpowiednie ikony.

ja też mam ten komunikat o błędzie w konsoli:

TypeError: Cannot read property 'id' of null 
    at http://ruby-on-rails-140223.nitrousapp.com:3000/assets/auctions/auctionCtrl-f2cb59b8ad51e03a2264ef2c6e759a54.js?body=1:33:52 
    at Array.some (native) 
    at hasWished (http://ruby-on-rails-140223.nitrousapp.com:3000/assets/auctions/auctionCtrl-f2cb59b8ad51e03a2264ef2c6e759a54.js?body=1:32:30) 
    at fn (eval at <anonymous> (http://ruby-on-rails-140223.nitrousapp.com:3000/assets/angular/angular-81b9b668c3f93c8ccb76b27ad984d9b6.js?body=1:13323:15), <anonymous>:4:318) 
    at Object.expressionInputWatch [as get] (http://ruby-on-rails-140223.nitrousapp.com:3000/assets/angular/angular-81b9b668c3f93c8ccb76b27ad984d9b6.js?body=1:14303:31) 
    at Scope.$digest (http://ruby-on-rails-140223.nitrousapp.com:3000/assets/angular/angular-81b9b668c3f93c8ccb76b27ad984d9b6.js?body=1:15819:40) 
    at Scope.$apply (http://ruby-on-rails-140223.nitrousapp.com:3000/assets/angular/angular-81b9b668c3f93c8ccb76b27ad984d9b6.js?body=1:16098:24) 
    at done (http://ruby-on-rails-140223.nitrousapp.com:3000/assets/angular/angular-81b9b668c3f93c8ccb76b27ad984d9b6.js?body=1:10547:47) 
    at completeRequest (http://ruby-on-rails-140223.nitrousapp.com:3000/assets/angular/angular-81b9b668c3f93c8ccb76b27ad984d9b6.js?body=1:10745:7) 
    at XMLHttpRequest.requestLoaded (http://ruby-on-rails-140223.nitrousapp.com:3000/assets/angular/angular-81b9b668c3f93c8ccb76b27ad984d9b6.js?body=1:10686:9) 

i po kliknięciu również ten błąd:

TypeError: v2.hasWished is not a function 
    at fn (eval at <anonymous> (http://ruby-on-rails-140223.nitrousapp.com:3000/assets/angular/angular-81b9b668c3f93c8ccb76b27ad984d9b6.js?body=1:13323:15), <anonymous>:4:318) 
    at Object.expressionInputWatch [as get] (http://ruby-on-rails-140223.nitrousapp.com:3000/assets/angular/angular-81b9b668c3f93c8ccb76b27ad984d9b6.js?body=1:14303:31) 
    at Scope.$digest (http://ruby-on-rails-140223.nitrousapp.com:3000/assets/angular/angular-81b9b668c3f93c8ccb76b27ad984d9b6.js?body=1:15819:40) 
    at Scope.$apply (http://ruby-on-rails-140223.nitrousapp.com:3000/assets/angular/angular-81b9b668c3f93c8ccb76b27ad984d9b6.js?body=1:16098:24) 
    at HTMLButtonElement.<anonymous> (http://ruby-on-rails-140223.nitrousapp.com:3000/assets/angular-touch/angular-touch-b4d02ed602708a1c93b51087222e0363.js?body=1:478:13) 
    at HTMLButtonElement.eventHandler (http://ruby-on-rails-140223.nitrousapp.com:3000/assets/angular/angular-81b9b668c3f93c8ccb76b27ad984d9b6.js?body=1:3299:21) 
+0

spróbuje użyć '(item.wishlists | filtr: {user_id: user.id}). Długość == 0' –

Odpowiedz

2

filtr powinien utwory:

<div ng-repeat="item in items"> 
    <h3>{{item.title}}</h3> 
    <a href="" ng-click="addToWishlist(item)" ng-if="!(item.wishlists|filter:{user_id:user.id}).length">Wish</a> 
    <a href="" ng-click="removeFromWishlist(item)" ng-if="(item.wishlists|filter:{user_id:user.id}).length">Undo-Wish</a> 
</div> 
+1

tak, niesamowite, działa! –

+2

Chciałbym unikać umieszczania tak dużej logiki w widoku, pamiętaj, oddzielenie obaw, ten kod byłby lepszy w funkcji wewnątrz kontrolera. –

+0

Musimy dodać dwa bloki 'ng-repeat' z tymi samymi filtrami, jeśli chcemy je renderować Żądane/spodziewane listy użytkowników, a wszystko będzie wyglądało dobrze. To nie jest logika. Po prostu wyświetla opcje. Ale zgadzam się, w każdym przypadku będzie to potrzebne w optymalizacji. Wtedy źródło danych zwróci znak boolowy w odpowiedzi. –

1

Nie używaj indexOf, sprawdź ten post: „Jest jedna Ostatni aspekt do rozważenia: równość Metoda indexOf używa ścisłej równości (===) do określenia, czy element pasuje do twojego wyszukiwania.To działa doskonale dla prymitywów takich jak łańcuchy i liczby.Ale możesz mieć trudności z wykorzystaniem indexOf do wyszukiwania danego obiektu lub tablica " finding-array-elements-with-array-indexof

Możesz użyć $ filter API Reference/ng/filter components in ng/filter, lub może powinieneś utworzyć funkcję w swoim sterowniku, przekazując jako paremetry bieżący element i user.id, aby to zrobić lub utwórz niestandardową dyrektywę.Zaznacz jeśli chcesz pomysł dla funkcji niestandardowej: how-to-find-index-of-an-item-in-javascript-object-array/

Pozdrowienia

2

nie można korzystać z funkcji IndexOf dla tego zadania. zamiast polecam Ci stworzyć funkcję w zakresie w kontrolerze, który sprawdza, czy lista życzeń zawiera użytkownikowi w ten sposób -

function isUserOnWishlist(item) { 
    return item.wishlists.some(function(wishlist) { 
     return wishlist.user_id === user.id; // (on $scope ?) 
    }); 
} 

na widoku -

<a href="" ng-click="addToWishlist(item)" ng-if="!isUserOnWishlist(item.wishlists)">Wish</a> 
<a href="" ng-click="addToWishlist(item)" ng-if="isUserOnWishlist(item.wishlists)">Undo-Wish</a> 

funkcja isUserOnWishlist będzie iteracyjne na każdym użytkowniku na liście życzeń i zwracaj true tylko wtedy, gdy znajdzie co najmniej jedną listę życzeń, która ją przekazuje - wishlist.user_id === user.id. mogłeś użyć funkcji indexOf, jeśli lista życzeń była listą obiektów listy zamiast int.

Polecam zapoznanie się z dokumentacją funkcji macierzy MDN js, można znaleźć tam wyjaśnienie o wszystkich funkcjach super-tablicy, która wychodzi z pudełka z js.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array

powodzenia.

+0

Witam, używam to teraz działa ale jeśli lista życzeń jest pusta, pojawia się ten błąd: 'TypeError: Nie można odczytać właściwości 'id' o wartości null w Array.some (macierzystym)' - jak mogę to rozwiązać? –

+0

Czy jesteś pewien, że zmienna użytkownika nie ma wartości NULL? –

+0

Tak, używam 'return wishlist.user_id === Auth._currentUser.id' zamiast user.id. (Zaktualizuję moje pytanie, aby pokazać wam, co teraz robię razem) –