Wie vermeide ich eine Statusduplizierung zwischen übergeordneten und untergeordneten Bildschirmen, wenn von untergeordneAndroid

Forum für diejenigen, die für Android programmieren
Anonymous
 Wie vermeide ich eine Statusduplizierung zwischen übergeordneten und untergeordneten Bildschirmen, wenn von untergeordne

Post by Anonymous »

In Jetpack Compose mit MVVM habe ich einen übergeordneten Bildschirm, der drei untergeordnete Bildschirme enthält. Die Navigation wird verwendet, um zwischen den untergeordneten Bildschirmen zu wechseln.
Jeder untergeordnete Bildschirm kann auf unterschiedliche Weise ein PDF generieren:
  • Einer lädt es aus dem Internet herunter.
  • Ein anderer generiert es lokal.
  • Ein anderer erstellt es möglicherweise aus Datenbankdaten.
Unabhängig davon, wie sie generiert werden, müssen alle drei untergeordneten Bildschirme dazu in der Lage sein an:
  • Zeigen Sie das PDF an.
  • Senden Sie es per E-Mail.
  • Drucken Sie es aus.
Das Problem besteht darin, dass diese drei Aktionen den Code auf allen untergeordneten Bildschirmen duplizieren. Um Duplikate zu vermeiden, habe ich darüber nachgedacht, die Logik zum Anzeigen, Senden und Drucken der PDF-Datei auf den übergeordneten Bildschirm zu verschieben. Die einzige Möglichkeit, die ich mir vorstellen kann, ist:
  • Jeder untergeordnete Bildschirm speichert das generierte PDF in seinem eigenen uiState.
  • Im untergeordneten Composable verwende ich einen LaunchedEffect, um zu erkennen, wann sich das
    PDF ändert.
  • Wenn es sich ändert, rufe ich eine Funktion im übergeordneten Element auf und übergebe das PDF
    nach oben.
Hier ist ein vereinfachter Ausschnitt, wie der Elternteil das PDF von einem Kind erhält:

Code: Select all

composable(InfractionsDestinations.Pending.name) {
PendingScreen(
infractions = uiState.pendingInfractions,
onPDFDisplayRequested = { pdf ->
vm.showPDF(pdf = pdf)
}
)
}
Das Problem besteht darin, dass jetzt sowohl das übergeordnete als auch das untergeordnete Element die PDF-Datei in ihrem eigenen uiState speichern, da diese zum Anzeigen, Senden oder Drucken verwendet wird und daher aufbewahrt werden muss. Dies verstößt gegen das Prinzip der Single Source of Truth (SSOT).
⚡ Mini-Beispiel des Problems
Untergeordnetes ViewModel:

Code: Select all

data class PendingScreenUiState(
val loading: Boolean = false,
val pdf: PDF? = null
)

class PendingScreenViewModel : ViewModel() {
private val _uiState = MutableStateFlow(PendingScreenUiState())
val uiState: StateFlow
 = _uiState

fun buildPDF(context: Context, infraction: InfractionWithDetails) {
viewModelScope.launch {
val pdfFile = PDFUtils.generateProvisionalPDF(context, infraction)
if (pdfFile.exists()) {
val bulletinPDF = PDF(pdfFile)
_uiState.update { it.copy(pdf = bulletinPDF) }
}
}
}
}
Untergeordnetes Composable:

Code: Select all

@Composable
fun PendingScreen(
infractions: List,
vm: PendingScreenViewModel = koinViewModel(),
onPDFDisplayRequested: (PDF) -> Unit
) {
val uiState by vm.uiState.collectAsStateWithLifecycle()

LaunchedEffect(uiState.pdf) {
uiState.pdf?.let { onPDFDisplayRequested(it) }
}

// ... rest of the UI
}
Gibt es eine sauberere Strategie, die den empfohlenen Compose + MVVM-Prinzipien (wie SSOT und State-Hoisting) folgt, um mit dieser Situation umzugehen?
Im Moment fühle ich mich gezwungen, das PDF sowohl im untergeordneten als auch im übergeordneten Status zu duplizieren, was sich nicht richtig anfühlt. Gibt es ein empfohlenes Muster, um die PDF-Verarbeitung im übergeordneten Element zu zentralisieren und es dennoch jedem untergeordneten Element in seinem eigenen ViewModel generieren zu lassen?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post