2015-08-21 15 views
6

KontekstCzysty projekt dla scentralizowanej nawigacji?

pojedyncze strony/ajax web app

Podstawowa struktura kodu

LocationManager (odpowiedzialny za aktualizowanie hash przeglądarki i przełączania lokalizację aplikacji do innej płytki)

Przepływ strony/płytek

Podstawowe informacje> Informacje bytowe> Vehicle Information> Opcje zakupu> Przegląd Zamówienie> Enter Płatność i przedłożyć

Problem

Gdy użytkownik nawiguje z możliwości zakupu na Przeglądzie zleceń, długa (5- 8 sekund) wezwanie serwisowe służy do obliczania szczegółów zamówienia. Po rozstrzygnięciu połączenia wywołanie zwrotne ma na celu nawigację użytkownika do strony zamówienia recenzji. Problem polega na tym, że jeśli użytkownik kliknie z powrotem w tym czasie i wróci do informacji gospodarstwa domowego, jak tylko połączenie zostanie rozstrzygnięte, zostaną oni "automatycznie" przeniesieni do zamówienia przeglądu. Bardzo niezręczne wrażenia użytkownika.

Ograniczenia

Anulowanie połączenia nie jest rozwiązaniem. Potrzebujesz rozwiązania do obsługi nawigacji.

Aktualny proponowana realizacja

Zapisz "currentLocation" przed dokonaniem połączenia calculateOrder. Przeprowadź "currentLocation" w oddzwanianiu do metody setLocation zgodnie z przeznaczeniem StartStartingPoint. Wewnątrz setLocation metoda if(intendedStartingPoint === Locationmanager.currentLocation) {//Navigate}

Podsumowując, jeśli użytkownik zmieni położenie, podczas gdy rozmowa jest w toku, po uchwale zawinięcia jest, nie będziemy poruszać ponieważ użytkownik nie spodziewa się poruszać na Przeglądzie zleceń w tym momencie.

To działa, prawda?

The Catch

Mamy wiele miejsc w aplikacji gdzie setLocation nazywa ciągu zwrotnego dla długotrwałych rozmowy. Oznacza to, że będę musiał zaktualizować wszystkie wywołania setLocation za pomocą nowego parametru - objectiveStartingPoint. Chociaż ma to dla mnie sens, wygląda na to, że ma potencjał, by się trochę zagracić.

Jakieś pomysły, jak to oczyścić i zcentralizować?

+0

zawinąć wywołanie setLocation w wyspecjalizowanych funkcji, dostarczyć go do zwrotnego weryfikacja zamówienia i dokonać specjalistyczna funkcja również przyjmuje parametr desiredStartingPoint jako parametr i obsługuje logikę predictStartingPoint? – Soggiorno

+0

Co powiesz na wyłączenie przycisku Wstecz (lub dowolnej akcji) do momentu, aż połączenie zostanie przywrócone? W przeciwnym razie po prostu sprawdź swoją aktualną lokalizację na wezwanie powrotu i przekierowanie tylko, jeśli na prawym kafelku. (Uwaga: w tym przypadku problem może nadal powracać użytkownik, który modyfikuje niektóre dane, a następnie powraca do właściwego kafelka bez ponownego uruchamiania połączenia, co powoduje przekierowanie bez zapisywania/weryfikacji nowych danych, więc powinieneś najmniej automatycznie ponownie uruchomić wywołanie zmiany danych, ale po prostu anulowanie połączenia w sprawie zmiany nawigacji/danych byłoby o wiele bardziej idealne.) –

+0

@ SzabolcsPáll nie można wyłączyć przycisków przeglądarki na stronie internetowej. Rozwiązanie, które zaproponowałeś w inny sposób, zostało opisane w pytaniu. – antonpug

Odpowiedz

5

W tej chwili użytkownik może kliknąć przycisk Oblicz na stronie Opcje zakupów. Następnie wyświetla się wskaźnik obciążenia (na szczęście) i wysyła asynchroniczne żądanie do serwera z dołączoną setLocation('ReviewOrder'). W aplikacji jest wiele miejsc, w których używasz tego wzorca.

Występuje problem przekierowań nieoczekiwanych (z punktu widzenia użytkownika), ponieważ dzięki temu podejściu odzyskiwane są dane serwera i nawigacja interfejsu użytkownika. Rozwiązaniem, które przychodzi na myśl, jest rozłączenie ich i usunięcie wszystkich długotrwałych żądań kontynuacji. Może działać w następujący sposób.

Gdy użytkownik kliknie przycisk Oblicz, zaczynasz asynchronicznego żądania i jednocześnie natychmiast przejdź na stronę Przegląd zamówienia (jest to istotne z punktu widzenia UX ponieważ użytkownicy teraz jasno zrozumieć, że przycisk Oblicz nawiguje do Przegląd zamówienia). Na stronie Zlecenie przeglądu wyświetl wskaźnik ładowania z informacją "czekaj, pozostało około 10 sekund ..." Po zakończeniu żądania ukryj wskaźnik ładowania i wyświetl dane.

W ten sposób użytkownicy będą mieli spójny interfejs użytkownika, wiedząc, że za każdym razem, gdy klikną przycisk w aplikacji, dzieje się to samo (nawigują do widoku) i nie ma zaskakujących automatycznych przekierowań.

0

Przede wszystkim, jeśli użytkownik może wrócić i zmienić wprowadzone informacje na poprzednich stronach, musi unieważnić wszelkie oczekujące zgłoszenia serwisowe. Jeśli zgłoszenie serwisowe w oparciu o nieaktualne informacje wraca, należy je odrzucić.

Oznacza to, że if(intendedStartingPoint === Locationmanager.currentLocation) {//Navigate} jest niewystarczające. Musisz zrobić coś takiego, jak if(intendedStartingPoint === Locationmanager.currentLocation && /* no information altered in the meantime*/) {//Navigate}.

Teraz za pytanie projektu: Jest to trochę trudne do skonstruowania tego bez jakiegokolwiek kodu betonu, ale można wykonać następujące czynności:

  • zapewnić środki do rejestracji i zarządzania długo działa połączeń w LocationManager
  • długo działające połączenia powinien wtedy zawsze być zarejestrowani w LocationManager
  • LocationManager powinny zapewnić, że co najwyżej jeden długotrwały połączenie jest aktywne w momencie
  • Jeżeli wystąpi jakakolwiek zmiana lokalizacji , wszystkie (lub jedna aktywna) długo trwająca rozmowa musi zostać unieważniona.
  • Odwołanie długotrwałego połączenia powinno sprawdzić, czy nie zostało unieważnione, i tylko nawigować, jeśli tak jest. LocationManager może to zrobić w zunifikowany sposób dla wszystkich oddzwonień.
  • Nowe, długotrwałe połączenia mogą zastąpić/unieważnić trwające połączenie lub zostać odrzucone, jak chcesz.

Mam nadzieję, że ma to sens w konkretnej sytuacji.

1

Najpierw oblicz szczegóły zlecenia za pomocą wywołania asynchronicznego i pokaż/symuluj pasek postępu dla użytkownika końcowego za pośrednictwem javascript.

Druga rzecz: nie wymuszaj otwarcia kafli ReviewOrder w swojej funkcji oddzwaniania serwisowego. Po zakończeniu obliczania usługi funkcja zwrotna sprawdza bieżący kafelek, a jeśli nie jest to kafelek ReviewOrder, przechowuje obliczone informacje w Sesji lub pamięci lokalnej.

Gdy użytkownik porusza się po kafelku ReviewOrder, porównaj szczegóły zamówienia, które pochodziły od użytkownika z przechowywanymi szczegółami zamówienia (np. Za pomocą funkcji mieszania).

Jeśli hashody szczegółów zamówienia użytkownika i zapisane szczegóły zamówienia są takie same, wyświetl zapisane informacje o zamówieniu, w przeciwnym razie ponownie wywołaj usługę.

Ważna uwaga: aby zapobiec zamówienie kucie, rozważmy następujący sposób:

Przy obliczaniu szczegóły zamówienia na serwerze, generuje unikatowy identyfikator zamówienia, które zostaną zwrócone użytkownikowi. Następnie zapisz szczegóły obliczonego zamówienia wraz z tym id w bazie danych serwera. Jeśli użytkownik nie zmienił szczegółów zamówienia, skrypt umieści na serwerze tylko ten identyfikator zamówienia jako znak, że zamówienie zostało zaakceptowane. Następnie przeczytaj bazę danych i przetwórz zamówienie według tego identyfikatora.

Jeśli zamówienie nie zostało zakończone, zastosuj zaplanowane zadanie, które wyczyści bazę danych z niezakończonych zamówień (na przykład - zamówienia, obliczone 24 godziny temu, ale nadal nie zostały zakończone).

2

Ponieważ nie można uniemożliwić użytkownikowi poruszania się po kafelkach, powiadomienie jej o opóźnieniu obliczeniowym nie rozwiąże całego problemu. Możesz poinformować użytkownika o przybliżonym czasie do ukończenia, możesz wyświetlić pasek postępu i możesz zabrać ją natychmiast do kafelka Polecenie ponownego przeczytania, aby poczekać na wyniki, ale jeśli odejdzie od kafelka, pozostaniesz przy swoim oryginalny problem.

Jeśli użytkownik zdecydował się na nawigację po tych wszystkich informacjach, musiała podjąć świadomą decyzję o przerwaniu postępowania. To byłby zły UX, który przetransportował ją z powrotem do Zakonu Recenzji. Co teraz?

Proponujesz, całkiem rozsądnie, że funkcja zwrotna wysłana z calculateOrder powinna przekazać parametr intendedStartingPoint do setLocation. Obawiasz się, że wymagałoby to zmodyfikowania każdego połączenia do setLocation, aby uwzględnić nowy parametr. Nigdy się nie obawiaj, JavaScript oferuje schludny sposób na rozwiązanie tego dylematu. Możesz dodać nowy parametr do setLocation bez modyfikowania istniejących połączeń. Wymaga to jedynie, aby intendedStartingPoint był ostatnim argumentem na liście argumentów . Następnie nowa wersja setLocation może sprawdzić wartość intendedStartingPoint, aby sprawdzić, czy jest to undefined.

Jeśli intendedStartingPoint jest undefined, wiesz, że setLocation odbiera jeden ze starych połączeń, te, które nie przeszły intendedStartingPoint. W takich przypadkach należy zignorować numer intendedStartingPoint i postępować jak poprzednio. W przeciwnym razie porównamy intendedStartingPoint z bieżącą lokalizacją i postępujemy zgodnie z wynikiem porównania.

Jeszcze lepszym podejściem byłoby uczynienie nowego parametru nie intendedStartingPoint, ale obiekt o nazwie options, który zawiera intendedStartingPoint jako jeden z jego atrybutów. Umożliwia to przekazanie dalszych opcjonalnych wartości do setLocation, jeśli zajdzie taka potrzeba w przyszłości.

Nowe zachowanie setLocation jest dość proste. Przed ustawieniem nowej lokalizacji należy sprawdzić, czy intendedStartingPoint jest równe bieżącej lokalizacji. Jeśli tak, nie musisz nic robić, ponieważ użytkownik jest już tam, gdzie ma być.Ale jeśli intendedStartingPoint różni się od obecnej lokalizacji, użytkownik ma poruszać się, więc można zrobić coś takiego:

if (LocationManager.currentLocation !== options.intendedStartingPoint) { 
    // Tell the user that the calculation has finished. 
    // Ask her if she wants to return to Review Order now. 
}