2013-02-01 14 views
5

Po załadowaniu mojej aplikacji rejestruję filtr i usługę z kanciastą. Ale filtr próbuje wykonać zanim usługa wróci z danymi, więc moja kolekcja przedmiotów szczeka w filtrze. Miałem skrzypce, ale nie wiem, czy można użyć $ http w skrzypcach, ponieważ jest to zasób zewnętrzny. Oto, co mam Fiddle Przepraszam, że tak naprawdę nie działa. to było dużo. Myślę, że moim problemem jest wyczucie czasu. Potrzebuję filtra, aby poczekać na odpowiedź HTTP lub po prostu nie "wymuszać" samego siebie.

Błąd, który otrzymuję teraz, to "elementy są niezdefiniowane", ponieważ właśnie tam zastosowano filtr. Zrobiłem to działa zanim spróbowałem złączyć połączenie http w usługę. Ale czuję, że to jest kanciasty sposób i "po prostu chcę być w zgodzie".

Kiedy mój kontroler odpala to sprawia, że ​​połączenia do pobierania danych:

eventApi.async().then(function() { 
    $scope.eventCollection = eventApi.data(); 
}); 

ale zanim wróci filtr jest stosowany w HTML:

<tr ng:repeat="event in events | myEventFilter:ddlFilter | 
     orderBy:sort.column:sort.descending"> 

Fiddle

+1

również działa po ustabilizowaniu się pyłu.po prostu wyrzuca początkowo mnóstwo błędów o filtrze, które nie mają żadnych elementów do obsłużenia z – VBAHole

+1

Zamiast $ http, użyj $ timeout (z limitem czasu, powiedzmy 2 sekundy), aby zasymulować opóźnienie w jsfiddle. Wewnątrz callback'a timeout, zakoduj swoje dane tak, jakby wróciły z serwera. Opublikuj to działające skrzypce, a przyjrzymy się (bo twoje skrzypce ma więcej niż tylko błędy HTTP). –

+0

Oto widelec skrzypiec, który rozwiązuje kilka innych problemów: (1) eventApi nie został wprowadzony do kontrolera i (2) główny moduł aplikacji nie był zależny od modułu chartApp. http://jsfiddle.net/BinaryMuse/WwR4U/ –

Odpowiedz

8

Oto widelec zaktualizowanego skrzypiec, który naprawia kilka pominiętych zależności (eventApi nie wstrzyknięto do kontroler, $timeout nie wstrzyknięto do usługi eventApi). Moje komentarze będą oparte na tym kodzie: http://jsfiddle.net/BinaryMuse/zww7e/1/

To skrzypce z powodzeniem przenosi nas do problemu, o którym napisałeś: "Nie można odczytać właściwości 'length' of undefined" w twoim filtrze. Ogólnie rzecz biorąc, filtry powinny domyślnie obsługiwać wartości puste/niezdefiniowane. Po prostu zmodyfikuję filtr, żeby przeczytać coś takiego:

return function (items, eventFilterType) { 
    var arrayToReturn = []; 
    if (items === undefined) return arrayToReturn; 
    // ... 
} 

To powinno zająć się Twoim problemem root; skrzypce działa teraz bezbłędnie, chociaż wydaje się, że nie działa poprawnie; o ile mogę to stwierdzić, dzieje się tak dlatego, że ustawiasz $scope.eventCollection zamiast $scope.events w sekcji if (live) kontrolera. Wprowadzenie tej zmiany powoduje, że dane faktycznie pojawiają się w widoku.

Jednakże, może być zainteresowany w innym mieniu kątowej: w przypadku korzystania z obietnicy zbudowany z $q można powiązać widoku bezpośrednio do obietnicy, a widok będzie traktować go tak, jakbyś związany go do rozwiązana wartość obietnicy.Tak więc, na przykład, można wykonać następujące czynności:

// in the service 
$timeout(function() { 
    deffered.resolve(fakeEvents); // <-- resolve with the data 
}, 2000); 
return deffered.promise; 

// in the controller 
if (live) { 
    $scope.events = eventApi.async(); 
} 

Oto zaktualizowana wersja skrzypcach, który demonstruje tę technikę: http://jsfiddle.net/BinaryMuse/zww7e/2/

[Update]

Jak zauważył Jeff w komentarze, Angular jest przestarzałe automatyczne rozpakowanie obietnicy; można see the commit here, ale tutaj jest komunikat:

fix ($ parse): potępiać obietnica rozpakowanie i sprawiają, że opt-in

Ten popełnić wyłącza obietnicy rozpakowaniu i dodaje $ parseProvider.unwrapPromises() aplet geter/setter, który umożliwia deweloperom ponowne włączenie funkcji w razie potrzeby. Promise unwrapping pomoc zostanie usunięta z Angular w przyszłości, a to ustawienie zezwala tylko na włączenie go w okresie przejściowym.

Po rozpakowaniu Angular zarejestruje ostrzeżenie o każdym wyrażeniu, które odwija ​​obietnicę (w celu zmniejszenia szumu, każde wyrażenie jest rejestrowane tylko w jednostkach). Aby wyłączyć to rejestrowanie, należy użyć $parseProvider.logPromiseWarnings(false).

Wcześniej obietnice znaleziono nigdzie w ekspresji podczas ekspresji oceny oceni undefined podczas nierozwiązany i wartości spełnienie jeśli spełnione.

Jest to cecha, która nie okazać się szalenie użyteczne lub popularne, głównie ze względu na dychotomii dostępu do danych w szablonach (dostępne jako wartości surowców) i kod sterowania (dostępne jako obietnic).

W większości kodu ostatecznie rozwiązaliśmy obietnice ręcznie w kontrolerach lub automatycznie poprzez trasowanie i ujednolicenie dostępu do modelu w ten sposób.

Inne downsides automatycznego obietnicy odpakowanie:

  • przy budowie komponentów to często pożądane, aby otrzymać surowe obietnic
  • zwiększa złożoność i spowalnia oceny ekspresji
  • sprawia kod ekspresja pre-generacja nieatrakcyjne ze względu na ilość kodu, który musi zostać wygenerowany:
  • powoduje automatyczne uzupełnianie IDE i obsługę narzędzi twardych
  • dodaje zbyt wiele magii

ZMIANA ZMNIEJSZENIA: $ parsowanie i szablony w ogóle nie będą już automatycznie odwijać obietnic od . Ta funkcja została uznana za przestarzałą i jeśli jest bezwzględnie potrzebna, może zostać ponownie włączona w okresie przejściowym za pośrednictwem interfejsu API $parseProvider.unwrapPromises(true).

+3

niewiarygodne! Dziękuję bardzo. kanciasty był dużo zabawy, gdy działa i dużo zgaga, gdy nie. ale społeczność jest niesamowita i wszyscy byli bardzo pomocni. myślę, że samo w sobie jest bezpośrednim odbiciem tego faktu, że struktura działa. – VBAHole

+1

Szczęśliwy, że pomógł! Miałem podobne doświadczenia, ale po kliknięciu jest świetnie! –

+1

Użyłem powyższej techniki podczas analizowania wartości dat: 'if (value === undefined) return new Date(); return new Date (parseInt (value.substr (6))); ' –

Powiązane problemy