Как обрабатывать выбор и обновление в MVVM?IOS

Программируем под IOS
Ответить
Anonymous
 Как обрабатывать выбор и обновление в MVVM?

Сообщение Anonymous »

Я играю с MVVM и испытываю проблемы с обворачиванием моей головы, как работать с выбором одного элемента.struct NoteListView: View {
@State private var model = NoteModel()

var body: some View {
NavigationStack {
List(model.notes) { note in
NavigationLink {
NoteDetailView(note: note)
} label: {
Text(note.title)
}
}
.task {
model.fetchNotes()
}
}
}
}

struct NoteDetailView: View {
let note: Note

var body: some View {
Text(note.title)
.font(.title)
Text(note.content)
}
}

@Observable
class NoteModel {
var notes: [Note] = []

func fetchNotes() {
self.notes = [
Note(title: "First note", content: "Test note"),
Note(title: "Reminder", content: "Don't forget to water the plants!"),
Note(title: "Shopping list", content: "Eggs, milk, hat, bread")
]
}
}

struct Note: Identifiable, Hashable {
let id = UUID()
var title: String
var content: String
}
< /code>
Теперь я хочу обновить примечание в представлении подробностей. Обновление включает в себя запрос PUT на сервер с сервером, вычисляющим данные для обновления, поэтому после успешного запроса необходимо извлечь новую версию ноты. Кажется, я не могу понять, как это написать. Я думаю, что модель будет выглядеть примерно так.@Observable
class NoteModel {
var notes: [Note] = []
var selectedNote: Note?

func fetchNotes() {
self.notes = [
Note(title: "First note", content: "Test note"),
Note(title: "Reminder", content: "Don't forget to water the plants!"),
Note(title: "Shopping list", content: "Eggs, milk, hat, bread")
]
}

func fetchNote(title: String) {
// fetch a single note, probably used after updating a note to display the updated note on the details view
self.selectedNote = APIClient.fetchNote()
}

func updateNote(title: String, content: String) {
self.selectedNote?.title = title
self.selectedNote?.content = content
// makes a PUT request to update the note, after which the note needs to be fetched
}
}
< /code>
Но я не знаю, как передать выбранную заметку в представление подробностей и как обновить примечание, отображаемое в представлении «Подробности» и в представлении списка. Я полагаю, что это довольно базовый сценарий для MVVM, но я не мог найти никаких примеров, иллюстрирующих основные соглашения о том, как это сделать. В приведенном ниже код кнопка обновления изменяет заголовок и текст примечания в представлении подробностей. Навигация обратно сбрасывает список заметок, потому что модификатор .task {} < /code> снова запускается, «извлечение» списка жестко-кодированного.

Это работает, но кажется неуклюжим, чтобы пройти конкретную ноту и модель.struct NoteListView: View {
@State private var model = NoteModel()

var body: some View {
NavigationStack {
List($model.notes) { $note in
NavigationLink {
NoteDetailView(note: $note, model: model)
} label: {
Text(note.title)
}
}
.task {
model.fetchNotes()
}
}
}
}

struct NoteDetailView: View {
@Binding var note: Note
var model: NoteModel

var body: some View {
Text(note.title)
.font(.title)
Text(note.content)

Button("Update") {
let updatedNote = Note(id: note.id, title: "\(note.title) (updated)", content: "Updated text!")
model.updateNote(note: updatedNote)
}
}
}

@Observable
class NoteModel {
var notes: [Note] = []
var selectedNote: Note?

func fetchNotes() {
print("Fetching notes...")
self.notes = [
Note(title: "First note", content: "Test note"),
Note(title: "Reminder", content: "Don't forget to water the plants!"),
Note(title: "Shopping list", content: "Eggs, milk, hat, bread")
]
}

func updateNote(note: Note) {
if let index = notes.firstIndex(where: { $0.id == note.id }) {
notes[index] = note
}
}
}

struct Note: Identifiable, Hashable {
let id: UUID
var title: String
var content: String

init(id: UUID = UUID(), title: String, content: String) {
self.id = id
self.title = title
self.content = content
}
}


Подробнее здесь: https://stackoverflow.com/questions/797 ... te-in-mvvm
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»