HarmonyOS 鸿蒙Next @Observed和@ObjectLink能更新数据,但是ForEach无法更新渲染
HarmonyOS 鸿蒙Next @Observed和@ObjectLink能更新数据,但是ForEach无法更新渲染
我定义了一个用@Observed修饰的类:
class ChildData{
ChildText?: string
ChildImage?: Array<string>
ChildUrl?: Array<string>
Children?: Array<ChildData>
constructor(ChildText?: string,ChildImage?: Array<string>,ChildUrl?: Array<string>,Children?: Array<ChildData>) {
this.ChildText = ChildText
this.ChildImage = ChildImage
this.ChildUrl = ChildUrl
this.Children = Children
}
}
然后在一个自定义组件里专门嵌套:
@Component
struct ChildTag{
@Consume opa: number
@Consume fontSize: number
[@ObjectLink](/user/ObjectLink) Children: ChildData
build(){
Row(){
Text(this.Children.ChildText).width(100).fontSize(this.fontSize).backgroundColor(Color.Transparent).border({ width: 1, color: 0x3AB7C1, radius: 10, style: BorderStyle.Solid })
Button({type: ButtonType.Circle, stateEffect:true}){
Image($r('app.media.ic_public_list_add_light'))
.height('24vp')
.width('24vp')
}
.height('24vp')
.width('24vp')
.backgroundColor(0xf1f3f5)
.opacity(this.opa)
.animation({duration:100})
.onClick(() => {
this.Children.Children.push(new ChildData('tagtest', [], [], []))
})
Column(){
ForEach(this.Children.Children, (item: ChildData, index: number) => {
ChildTag({ Children: this.Children.Children[index] })
}, (item: string, index: number) => item + index.toString())
}
}
}
}
但是这个ForEach它只有首次渲染的时候是正常的,后续点击按钮数据源是更新了,但是渲染不更新
有没有佬看看我哪里没注意没写好
更多关于HarmonyOS 鸿蒙Next @Observed和@ObjectLink能更新数据,但是ForEach无法更新渲染的实战教程也可以访问 https://www.itying.com/category-93-b0.html
@Observed class TestUnit{ name:string=’’
constructor(name:string) { this.name=name } }
@Observed class FormTest extends Array<TestUnit> {
constructor() { super() this.addList(‘test-1’)
} addList(name:string){ this.push(new TestUnit(name))
} }
@Component struct Test { @ObjectLink form:FormTest count:number=1 build() { Column(){ Text(‘title’).onClick(()=>{ this.form.addList(‘test-’+(++this.count)) console.log(’’+this.form.length) }) List(){ ForEach(this.form,(item:TestUnit)=>{ ListItem(){ TextInput({text:item.name}).onChange((value:string)=>{ item.name=value }) }.width(‘80%’).height(40) },(item:TestUnit,index)=>‘Test-’+index) }.width(‘100%’).height(‘85%’) }.width(‘100%’).height(‘100%’) } } @Entry @Component struct Second { @State forms:FormTest[]=[new FormTest()] build() { List(){ ForEach(this.forms,(item:FormTest,index:number)=>{ ListItem(){ Test({form:this.forms[index]}) }.width(‘100%’).height(100) },(item:FormTest,index:number)=>‘form-test-’+index) }.width(‘100%’).height(‘100%’) } }
更多关于HarmonyOS 鸿蒙Next @Observed和@ObjectLink能更新数据,但是ForEach无法更新渲染的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
- 第一,第二层数组一定要用
extend
- 第二,对于
ObjectLink
,传入时候不能用foreach
循环出来的item
,而是要用数组的index
来获取,不过这个只影响提示不影响具体使用
我这个里面的数组类型也是要嵌套同样自定义的对象,就是A里面的数组a也是Array,也是extend么?
谢谢,已经理解用法了,
这个UI刷新机制,真的是呵呵。想吐。
迭代了几次api好像好些了😂,
麻烦各位大佬帮忙看下, 数据第一次请求时, 数据和UI都发生变化, 当activeIndex发生变化时, 数据变化了, 但是UI没有更新,这个怎么解决
我也遇到这样的问题了,无法渲染:
以下是源代码:
@Preview
@Component
export default struct Watching {
@State isEdit: boolean = false;
@State isDisableDelete: boolean = false;
@State isSelected: boolean = false;
@State history: History[] = [];
async aboutToAppear(){
let str = await pref.getValue(CommonConstants.HISTORY,CommonConstants.HISTORY,'') as string;
console.log('fred',`获取收藏:str=${str}`)
this.history = JSON.parse(str) as History[];
this.history = this.history.filter(item => item.type == cacheType.favorite);
}
build() {
Column() {
//编辑
Row() {
Row({ space: 8 }) {
Text(!this.isEdit ? '编辑' : '退出').myWhiteFont()
Image(!this.isEdit ? $r('app.media.edit') : $r('app.media.cross')).width(18).height(18).fillColor(Color.White)
}.onClick(() => this.isEdit = !this.isEdit)
}.width('100%').justifyContent(FlexAlign.End).height(50).padding({ right: 10 })
//list表
Row() {
List({ space: 10 }) {
ForEach(this.history, ( item:History) => {
ListItem() {
Stack({ alignContent: Alignment.TopEnd }) {
Column({ space: 6 }) {
Image(item.coverImgUrl).width(113).height(185)
Text(item.title).myWhiteFont()
Text(`观看至${item.index}集`).fontColor(Color.Gray)
}
if (this.isEdit) {
Image(item.isSelected ? $r('app.media.selected') : $r('app.media.select'))
.width(30)
.height(30)
.onClick(() =>{
item.isSelected = !item.isSelected;
})
}
}
}
},(item:History) => item.id.toString())
}.lanes(3).alignListItem(ListItemAlign.Center)
}.width('100%').padding(6)
Blank()
//操作按钮
if (this.isEdit) {
Row() {
Button('全选').myButton().onClick((event: ClickEvent) => {
})
Button('删除').myButton().onClick((event: ClickEvent) => {
}).enabled(this.isDisableDelete).fontColor(this.isDisableDelete ? Color.White : Color.Gray)
}.width('100%')
}
}.width('100%').height('100%')
.linearGradient({ angle: GradientDirection.Top, colors: [['#0F0F0F', 0.0], ['#3B1B1C', 0.6], ['#3B1B1C', 1.0]] })
}
}
学习,
prop,link 只能同步基本数据类型,如果是数组对象比如
```typescript
[@Observed](/user/Observed)
objBean {
title:string;
}
A{
[@State](/user/State) obj:objBean[];
build(){
B({obj:$obj})
}
}
B{
[@ObjectLink](/user/ObjectLink) obj;
}
这样B能拿到么
你要拿到什么,你这段代码可以理解成想拿整个数组或者想拿数组里面的单个,
拿整个数组,
基本信息
- 项目名称: 示例项目
- 项目状态: 进行中
- 项目负责人: 张三
能,但不能这么写。你得是个二维数组objBean[][], 然后把objBean[0]传进去,
巧了,我刚回答了另一个问题跟你一样的。https://docs.openharmony.cn/pages/v4.0/zh-cn/application-dev/quick-start/arkts-observed-and-objectlink.md#%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84
这个文档二维数组部分需要每个字认真读一下,在对照着我的例子,就可以解决问题了
首次渲染用的是:
new ChildData('tagtest', [], [], [new ChildData('tagtest', [], [], []),new ChildData('tagtest', [], [], []),new ChildData('tagtest', [], [], [])])
首次渲染出来是:
然后,点击按钮将数据更新成了:
new ChildData('tagtest', [], [], [new ChildData('tagtest', [], [], []),new ChildData('tagtest', [], [], []),new ChildData('tagtest', [], [], []), new ChildData('you', [], [], []),new ChildData('you', [], [], []),new ChildData('you', [], [], [])])
但是没有更新渲染:
在HarmonyOS中,@Observed
和@ObjectLink
用于实现数据绑定,确保当数据发生变化时,UI能够自动更新。@Observed
用于标记一个类,表示该类是可观察的,@ObjectLink
用于标记一个属性,表示该属性与@Observed
类的实例绑定。
ForEach
是鸿蒙框架中用于动态生成UI组件的API,通常用于根据数据列表渲染多个UI元素。当@Observed
和@ObjectLink
绑定的数据发生变化时,ForEach
应该能够自动更新UI。
如果ForEach
无法更新渲染,可能的原因包括:
-
数据未正确绑定:确保
ForEach
的输入数据源是@Observed
类的实例,并且ForEach
中的每个元素都正确使用了@ObjectLink
进行绑定。 -
数据未触发更新:
@Observed
类的属性修改必须通过其setter方法进行,直接修改属性值不会触发UI更新。 -
ForEach的key未正确设置:
ForEach
需要一个唯一的key来标识每个元素,如果key未正确设置或重复,可能导致UI无法正确更新。 -
UI组件未正确实现:确保
ForEach
渲染的UI组件实现了@Component
注解,并且能够响应数据变化。 -
异步更新问题:如果数据更新是在异步操作中进行的,可能需要使用
@State
或@Prop
来确保UI能够正确响应数据变化。
检查以上几点,确保数据绑定和UI渲染的逻辑正确,可以解决ForEach
无法更新渲染的问题。