angular - Vad är det bästa sättet att dela upp NGXS-tillståndet i mindre hanterbara delar, men ändå hålla dem tillgängliga för varandra?
Kort historik över frågan:
Jag utvecklar en webbassistent för partyspelet Mafia, så målet är att lagra ett enskilt spel i NGXS. Här är Gitlab-repot
Spelet innehåller:
- Lista över spelare
- Lista över passerade dagar (från 0 till ungefär 5 (vanligtvis))
Spelarmodell
Varje dag har tre faser: Natt > Dag > Röst
Dagsmodell
För att upprätthålla denna komplexa dagsstruktur och registrera alla spelares handlingar behöver jag en riktigt stor mängd handlingar, så när GameState började bli enorm försökte jag dela upp det i delstater. Och här stötte jag på problemet med cirkulärt beroende.
Faktiskt har jag på något sätt lyckats lösa det, genom att läsa detta: https://github.com/ngxs/store/issues/632
Jag skapade CurrentDayState och PlayersState som barnstater, men i det här fallet verkar det vara ett dåligt tillvägagångssätt, eftersom på det här sättet:
- Jag kan bara komma åt tillståndet direkt, och selektorer med komplex logik är fortfarande otillgängliga vid denna tidpunkt.
- Jag lagrar bara aktuell dag och aktuell röst, och sedan lägger jag dem i arrayen days i
GameState, och det kommer att vara svårt att gå tillbaka till tidigare dagar om spelledaren behöver kolla viss information
Jag känner att mitt tillvägagångssätt är lite klumpigt, och jag kunde inte komma på någon bättre lösning. Jag skulle kunna lagra alla åtgärder i rot-GameState, men på det sättet skulle .ts-filen ta upp cirka 800 rader och det verkar vara en dålig idé för mig.
Frågan:
Finns det något sätt att göra NGXS-tillstånd modulärt, men låta varje del av det få åtkomst till selektorer från en annan del utan att stöta på problem med cirkulära beroenden? (Redan läst innebär problem, NGXS delstater ska vara oberoende av varandra och ska inte ha någon kontroll över varandra överhuvudtaget)
Svar #1
Ett sätt att närma sig detta skulle vara att betrakta varje butik som en databas-tabell och varje nytt tillstånd du skriver som en ny post/rad i tabellen. Genom att normalisera dina modeller kan du ha en spelarbutik och en dagbutik. Om du behöver hela historiken av dagar och spelartillstånd för en viss dag, kan du kontinuerligt införa nya tillstånd istället för att uppdatera nuvarande tillstånd. Spelare kan behöva ett attribut för att indikera tidpunkten för det givna tillståndet (som en främmande nyckel som pekar på det associerade dagstillståndet).
Selektorer kan skrivas för att ta det aktuella tillståndet eller slå upp ett givet tillstånd för en viss tid i spelets historia om detta är ett affärskrav. NGXS-dokumentationen om selektorer nämner att man kan slå ihop orelaterade tillstånd med Meta-Selektorer. Du kan överväga att använda dessa selektorer för att slå ihop det relevanta spelar- och dagtillståndet för ett givet uppslagsbehov.
Redigera 1: Att normalisera datan och lagra bilder löser de dubbla problem du nämnde om att ha fullständig spelhistorik och bibehålla fler hanteringstillstånd.
För den specifika frågan om att upprätthålla olika tillstånd utan cirkulärt beroende bör du undvika att importera två filer i varandra. Två sätt att hantera detta som jag kan tänka mig just nu:
Överväg var du behöver att staterna ska anslutas - välj en som grund för huvudsakligt affärsobjekt - och importera endast filerna på ett sätt till den staten.
Om ingen av tillstånden är grunden för det primära affärsobjektet, introducera ett tredje tillstånd som tjänar denna roll och importera de andra tillstånden till detta.
Använd sedan Meta-Selector som tillhandahålls av NGXS och anslut de relevanta tillstånden där.
t.ex.
export class DaysState{
@Selector([DaysState, PlayersState])
static getGameState(days, players) {
return [...days, ...players];
}
}
