HarmonyOS 鸿蒙Next对于面向协议 interface的ViewModel是否支持?还是说固定要求研发人员使用MVC架构?
HarmonyOS 鸿蒙Next对于面向协议 interface的ViewModel是否支持?还是说固定要求研发人员使用MVC架构?
目前[@ObjectLink](/user/ObjectLink)允许装饰的变量类型,必须为被[@Observed](/user/Observed)装饰的class实例,必须指定类型。
可参考文档:
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-observed-and-objectlink-V13#装饰器说明
更多关于HarmonyOS 鸿蒙Next对于面向协议 interface的ViewModel是否支持?还是说固定要求研发人员使用MVC架构?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
下面依次解答您的疑问:
- 如何让ViewModel中 items 的元素修改selected状态导致渲染???
监听嵌套类对象属性变化,参考文档:
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-observed-and-objectlink-V13
此处监听了IndexViewModel.IndexItemViewModel[].selected的变化,需要将IndexViewModel、IndexItemViewModel都用@Observed修饰。
- 如果让ViewModel中的数据, 可以让父子组件双向绑定??
如上参考文档,单独使用@Observed是没有任何作用的,需要搭配@ObjectLink或者@Prop使用。
子组件中@Prop只能父子单向同步,父子双向同步需要使用@ObjectLink,由于@ObjectLink只能修饰class,所以需要将子组件中@Prop viewModel: IndexItemViewModelType修改为:@ObjectLink viewModel: IndexItemViewModel
代码请参考:
interface IndexItemViewModelType {
name: string
selected: boolean
selectItem(): void
}
[@Observed](/user/Observed)
class IndexItemViewModel implements IndexItemViewModelType {
name: string
selected: boolean
constructor(name: string) {
this.name = name
this.selected = false
}
selectItem(): void {
this.selected = !this.selected
}
}
interface IndexViewModelType {
items: IndexItemViewModelType[]
}
[@Observed](/user/Observed)
class IndexViewModel implements IndexViewModelType {
items: IndexItemViewModelType[]
constructor() {
this.items = [
new IndexItemViewModel('测试数据1'),
new IndexItemViewModel('测试数据2'),
new IndexItemViewModel('测试数据3'),
new IndexItemViewModel('测试数据4'),
new IndexItemViewModel('测试数据5'),
new IndexItemViewModel('测试数据6'),
new IndexItemViewModel('测试数据7'),
]
}
}
@Entry
@Component
struct Index {
@State
viewModel: IndexViewModelType = new IndexViewModel()
build() {
Column() {
List({ space: 10 }) {
ForEach(this.viewModel.items, (item: IndexItemViewModelType, index: number) => {
ListItem() {
CustomRow({ viewModel: item })
}
.onClick(() => {
item.selectItem()
})
})
}
.width('100%')
.height('50%')
CustomRow({ viewModel: this.viewModel.items[0] })
CustomRow({ viewModel: this.viewModel.items[1] })
}
}
//接上面代码
@Component
struct CustomRow{
[@ObjectLink](/user/ObjectLink) viewModel: IndexItemViewModel
build() {
Column() {
Text(this.viewModel.name)
.fontColor(this.viewModel.selected ? Color.Red : Color.Green)
Button('name change').fontSize(20).onClick(() => {
this.viewModel.name = this.viewModel.name + "c1"
})
}
}
}