LVRS Storyboard Frame
mvvm.svx
Path: mvvm.svx
MVVM
LVRS MVVM 모델은 ViewModels ( ViewModelRegistry)에 의해 구현되며, PageRouter에서 방출되는 루트/뷰 바인딩 메타데이터입니다.
목적
- 논리 키로 뷰 모델 인스턴스를 등록합니다.
- 구체적인 뷰 ID(
viewId)를 모델 키에 바인딩합니다. - 한 번에 하나의 뷰만 하나의 모델 키를 변경할 수 있도록 쓰기 소유권을 명시적으로 제어합니다.
코어 API (ViewModels)
위치: backend/state/viewmodelregistry.h / backend/state/viewmodelregistry.cpp
등록 수명주기:
set(key, object)get(key)remove(key)clear()
바인딩 및 소유권:
bindView(viewId, key, writable)unbindView(viewId)claimOwnership(viewId, key)releaseOwnership(viewId, key?)canWrite(viewId, key?)ownerOf(key)
데이터 액세스 도우미:
updateProperty(viewId, property, value)updatePropertyByKey(viewId, key, property, value)readProperty(viewId, property)
상태/진단:
keys,views,bindings,owners,lastError
라우터 메타데이터에서 바인딩
PageRouter는 경로 메타데이터에 다음이 포함된 경우 자동으로 뷰를 바인딩할 수 있습니다.
viewModelKey또는modelKeyviewId(선택 사항, 기본값은 경로 경로 또는 생성된 ID)writable또는modelWritable
이를 통해 페이지별 상용구 없이 경로 수준 소유권 정책을 사용할 수 있습니다.
쓰기 소유권 규칙
두 조건이 모두 true인 경우에만 쓰기 액세스가 허용됩니다.
- 뷰는 모델 키에 바인딩됩니다.
- 뷰는 해당 키의 현재 소유자입니다.
소유권이 없거나 충돌하는 경우 API가 false를 반환하고 lastError를 설정하도록 작성하세요.
사용 패턴
import LVRS 1.0 as LV
Component.onCompleted: {
LV.ViewModels.set("Session", sessionViewModel)
if (!LV.ViewModels.bindView("SessionPage", "Session", true))
console.warn(LV.ViewModels.lastError)
}
function renameSession(nextName) {
if (!LV.ViewModels.updateProperty("SessionPage", "name", nextName))
console.warn(LV.ViewModels.lastError)
}
동작 원리
- 키와 보기 ID는 트림 기반 토큰 정규화를 통해 정규화됩니다.
- 키가 제거되면 소유권 맵(
key -> viewId)이 정리됩니다. ViewModels에 의해 부모로 연결된 고아 모델 객체는 키 참조가 더 이상 남아있지 않을 때 자동으로 처분됩니다.- 바인딩 업데이트는 신호 기반(
viewsChanged,ownershipChanged)이므로 QML 관찰자가 반응할 수 있습니다.
처리해야 할 실패 모드
viewId또는 키가 비어 있습니다.- 알 수 없는 키에 바인딩 중입니다.
- 다른 뷰가 키를 소유하고 있는 동안 쓰기 가능한 바인딩을 시도했습니다.
- 속성이 바인딩되지 않은 뷰 또는 알 수 없는 속성 이름에 기록됩니다.
고급 시나리오: 읽기 전용 세부 정보 + 쓰기 가능한 편집기
일반적인 패턴은 2 뷰가 동일한 모델 키에 바인딩되되 서로 다른 권한을 갖는 것입니다.
- 상세 페이지:
bindView("Detail", "RunVM", false) - 편집기 페이지:
bindView("Editor", "RunVM", true)
이를 통해 읽기 전용 구성 요소는 하나의 편집기 표면만 모델 속성을 변경할 수 있는 동안 상태를 표시할 수 있습니다.
소유권 이양 패턴
편집 가능한 표면을 전환하는 경우:
releaseOwnership(previousViewId, key)claimOwnership(nextViewId, key)- 다음 보기에서만 쓰기 업데이트를 실행합니다.
이 명시적 핸드오버는 자동 쓰기 거부를 방지하고 소유권 감사 가능성을 유지합니다.
쓰기 실패 디버깅
updateProperty*가 false를 반환하면 순서대로 검사합니다.
ViewModels.lastErrorViewModels.bindingsViewModels.owners- QObject에 대상 속성이 존재하는지 여부
대부분의 런타임 오류는 소유권 누락이나 속성 이름의 오타로 인해 발생합니다.