angular - Jak mohu předat data zpět na svou hlavní stránku v Ionic 2?
Mám aplikaci Ionic 2. Účelem aplikace je účastnit se kurzu. Jakmile je kurz otevřen, je uživatel označen jako účastník tohoto kurzu v vzdáleném API.
Tok dat je:
- Uživatel otevře kartu 'Třídy'.
- Aplikace požaduje od API data o 'třídách'. Každá třída obsahuje 'stav' pro toho uživatele.
- Uživatel vybere třídu. To otevře nový pohled v aplikaci pomocí
NavController.push(Page, { 'classes': classObjFromApi });. - Do zásobníku bylo přidáno několik stránek, každá z nich dostala předaný objekt
classes. - Na poslední stránce je API informováno, že aktuální třída byla převzata, a uživatel se může vrátit na kořenovou stránku pomocí
NavController.popToRoot()
Na hlavní stránce je zobrazen stav každé třídy („Nezahájeno“, „Probíhá“, „Dokončeno“). V bodě 5 výše uvedeného postupu je uživatel přesměrován zpět na hlavní stránku, ale ta obsahuje data z doby, kdy byla původně vytvořena, což zobrazuje třídu jako „Nezahájeno“, i když je nyní „Dokončeno“.
Jak mohu aktualizovat data na hlavní stránce z jiné stránky ve stacku? Předpokládal jsem, že popToRoot() přijme navParams, abych mohl zkontrolovat přítomnost těchto dat na hlavní stránce a použít je, pokud existují, nebo je požádat z API, pokud ne.
Mohu se tomu vyhnout znovuzískáním dat z API v metodě ionViewDidEnter, ale to znamená jeden požadavek na API/HTTP pokaždé, když uživatel tuto stránku zobrazí, i když aplikace data již má. Zdá se to nepořádné.
Raději bych nepoužíval interní úložiště, pokud se tomu mohu vyhnout, protože to způsobuje zpoždění při načítání stránky, jelikož musím čekat, až se data načtou z úložiště, než je zobrazím.
Takže moje otázka zní: jaký je nejlepší způsob, jak to udělat? Pokud je to předání dat do zobrazení, jak to udělám, když popToRoot() nepodporuje parametry navigace?
Odpověď č. 1
Nejlepší způsob, jak toho dosáhnout, je použitím Událostí:
Na své kořenové stránce se přihlaste k vlastní události, aby se kód spustil pokaždé, když je tato událost publikována:
import { Events } from 'ionic-angular';
constructor(public events: Events) {
events.subscribe('status:updated', (updatedData) => {
// You can use the updatedData to update the view
// ...
});
}
// Clean up the subscription when the page is about to be destroyed
ionViewWillUnload() {
this.events.unsubscribe('status:updated');
}
A publikujte tuto událost na jakékoli jiné stránce, když uživatel tyto údaje změní:
import { Events } from 'ionic-angular';
constructor(public events: Events) {}
yourMethod(): void {
// Your custom logic...
// ...
// Now you can publish the event to update the root page (and any other page subscribed to this event)
this.events.publish('status:updated', updatedData);
}
UPRAVIT
Další způsob, jak to udělat, by byl použitím sdílené služby a použitím Subject pro publikování/přihlašování k odběru změn. Výsledek by byl poměrně podobný Ionic Events, ale v tomto scénáři byste museli přidat sdílenou službu a pak ji používat, když jsou data aktualizována. Preferoval bych Ionic Events, ale pro každý případ, takto byste to mohli udělat:
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MySharedService {
public onDataChange: Subject<any>;
constructor() {
this.onDataChange = new Subject<any>();
}
public publishUpdate(newData): void {
// Send the data to all the subscribers
this.onDataChange.next(newData);
}
}
Takže nyní na vaší hlavní stránce se přihlaste k odběru změn pomocí sdílené služby
import { Subscription } from 'rxjs/Subscription';
// ...
private onDataChangeSubscription: Subscription;
constructor(public mySharedService: MySharedService) {
this.onDataChangeSubscription = mySharedService.onDataChange.subscribe(
updatedData => {
// You can use the updatedData to update the view
// ...
});
}
// Clean up the subscription when the page is about to be destroyed
ionViewWillUnload() {
this.onDataChangeSubscription.unsubscribe();
}
A budete muset použít také sdílenou službu při aktualizaci dat z jakékoli jiné stránky:
constructor(public mySharedService: MySharedService) {}
yourMethod(): void {
// Your custom logic...
// ...
// Now you can publish the event to update the root page (and any other page subscribed to this event)
this.mySharedService.publishUpdate(updatedData);
}
Tento přístup může být lepší, pokud potřebujete provést nějakou vlastní logiku pokaždé, když jsou data aktualizována, takže místo toho, abyste to dělali u každého odběratele, můžete to udělat jen ve sdílené službě a vysílat výsledek...
