当前位置: 首页 > 知识库问答 >
问题:

harmonyos - @Observed与@Objectlink注解的使用问题:该如何正确使用这两个注解实现对象数组的双向数据绑定?

邢骏
2024-06-11

麻烦请教大家一个问题,我在写一个demo的时候用到了@Observed与@Objectlink注解在对象数组中遇到了问题,以下是错误涉及的代码

@Observedexport default class TransListHis {  startContent: string  endContent: string  transNum: number  isCollect: boolean  constructor(startContent: string, endContent: string, transNum: number, isCollect: boolean) {    this.startContent = startContent    this.endContent = endContent    this.transNum = transNum    this.isCollect = isCollect  }}
import TransListHis from '../../model/TransListHis'@Componentexport default struct TransHisItem {  @ObjectLink TItem: TransListHis  build() {    Row() {      Row({ space: 5 }) {        Text(this.TItem.startContent)        Text(this.TItem.endContent)          .fontSize(14)          .fontColor('#ccabaaaa')          .textOverflow({ overflow: TextOverflow.Ellipsis })          .maxLines(1)      }      .width('80%')      Row({ space: 5 }) {        if (this.TItem.transNum > 1) {          Text(`${this.TItem.transNum}次`)            .fontSize(14)            .fontColor(Color.White)            .width('11%')            .height(18)            .borderRadius(10)            .backgroundColor('#ff868f92')            .textAlign(TextAlign.Center)        }        Image($r('app.media.sc'))          .width(15)          .onClick(() => {            this.TItem.isCollect = !this.TItem.isCollect          })          .fillColor(this.TItem.isCollect ? '#f4ea2a' : '#e6e6e6')      }    }    .width('100%')    .justifyContent(FlexAlign.SpaceBetween)  }}
import Constants from '../../common/Constants'import TransListHis from '../../model/TransListHis'import TransHisItem from '../TransHistoryView/TransHisItem'@Componentexport default struct TransHistory {  HisTittle: string = '历史记录'  clearHis: string = '清空历史记录'  @State collectColor: string = ''  @State HisList: TransListHis[] = Constants.transListHis  build() {    Column({ space: 10 }) {      Row() {        Text(this.HisTittle)          .fontSize(18)        Text(this.clearHis)          .fontSize(12)          .fontColor('#ff828080')      }      .width('100%')      .justifyContent(FlexAlign.SpaceBetween)      .margin({ bottom: 10 })      List({ space: 5 }) {        ForEach(this.HisList, (item: TransListHis) => {          ListItem() {            TransHisItem({ TItem: item })          }        })      }    }    .padding(10)  }}

在 TransHistory 的第27行 TransHisItem({ TItem: item }) 提示错误信息:Assigning the 'regular' decorated attribute 'item' to the '@ObjectLink' decorated attribute 'TItem' is not allowed.

我想在点击每行的图片时能通过isCollect值的改变修改图片的颜色

共有2个答案

张逸清
2024-06-11

代码是没有问题的,可以检查下sdk或者IDE,我这用5.0SDK可以正常运行,没有任何报错:

image.png

尉迟栋
2024-06-11

在您的代码中,您正在尝试将一个普通的对象(在这种情况下是item)赋值给一个用@ObjectLink装饰的属性(TItem)。@ObjectLink注解用于创建一个双向数据绑定,它期望绑定到一个响应式对象,这样当对象的状态改变时,视图能够自动更新。然而,当您通过ForEach循环遍历数组时,传递给TransHisItem组件的item并不是响应式的,因此不能直接用于@ObjectLink

为了解决这个问题,您需要将HisList数组中的每个对象转换为响应式对象。在ArkUI(或类似框架)中,这通常涉及使用框架提供的响应式数据结构的API。不过,由于您没有明确指出您正在使用的具体框架(可能是鸿蒙系统的ArkUI或其他类似框架),我将提供一个通用的概念性解决方案。

您需要在TransHistory组件中,将HisList数组中的每个对象转换为响应式对象。这通常涉及创建一个响应式类实例的数组,而不是直接存储普通的对象数组。

这里是一个简化的示例,展示了如何修改代码以实现这一点:

// 假设有一个方法可以将普通对象转换为响应式对象function makeReactive(item: TransListHis): ReactiveTransListHis {  // 这里应该使用框架提供的方法将item转换为响应式对象  // 伪代码:return new ReactiveWrapper(item);}@Componentexport default struct TransHistory {  HisTittle: string = '历史记录'  clearHis: string = '清空历史记录'  @State HisList: ReactiveTransListHis[] = Constants.transListHis.map(makeReactive); // 转换数组  // ... 其他代码保持不变 ...}

在上面的代码中,我添加了一个makeReactive函数(这个函数应该根据您使用的框架来实现),它将TransListHis对象转换为响应式对象ReactiveTransListHis。然后,在初始化HisList时,我使用数组的map方法将每个对象转换为响应式对象。

此外,TransHisItem组件也需要相应地更新,以接收响应式对象而不是普通对象:

@Componentexport default struct TransHisItem {  @ObjectLink TItem: ReactiveTransListHis // 假设ReactiveTransListHis是响应式对象类型  // ... 其他代码保持不变 ...}

最后,在TransHistorybuild方法中,您可以像之前一样使用ForEach循环,但是此时item已经是响应式对象了,因此可以直接赋值给@ObjectLink装饰的属性:

ForEach(this.HisList, (item: ReactiveTransListHis) => {  ListItem() {    TransHisItem({ TItem: item }) // 现在item是响应式的  }})

请注意,具体的实现细节(如如何创建响应式对象、框架的API等)将取决于您使用的具体框架。如果您使用的是鸿蒙系统的ArkUI,请查阅相关文档以了解如何创建和使用响应式数据。如果框架不支持直接将普通对象转换为响应式对象,您可能需要重构您的数据模型,使其一开始就使用响应式数据结构。

 类似资料:
  • 本文向大家介绍Vue使用.sync 实现父子组件的双向绑定数据问题,包括了Vue使用.sync 实现父子组件的双向绑定数据问题的使用技巧和注意事项,需要的朋友参考一下 1.前言 最近在vue 项目中有一个需求, 就是我需要根据不同的类型在页面中放不同的组件, 组件需要跟当前页面的数据进行双向绑定,如果都写在同一个页面 代码会显得比较多,毕竟我当前页面已经7-800行代码了 所以我需要把一些元素定义

  • 以下是问题的陈述: 给定一个整数数组,返回两个数字的索引,使它们相加到一个特定的目标。 示例: 给定nums=[2,7,11,15],target=9,因为nums[0]nums[1]=27=9,所以返回[0,1]。 如果nums是一个整数数组,则有两种可能的解决方案: 检查哈希表中是否存在恭维,否则插入哈希表。 如果NUM是一个双精度数组,我如何解决这个问题?

  • 本文向大家介绍vue数据双向绑定的注意点,包括了vue数据双向绑定的注意点的使用技巧和注意事项,需要的朋友参考一下 最近一个vue和element的项目中遇到了一个问题: 动态生成的对象进行双向绑定是失败 直接贴代码: 上面一个简单的element的表单;addClass就是我要将数据绑定到的对象;他初始是一个空对象;我需要在其他地方读取然后给他添加属性,同时给表单进行绑定。 在这个过程中就发现,

  • 本文向大家介绍实例解析如何正确使用Java数组,包括了实例解析如何正确使用Java数组的使用技巧和注意事项,需要的朋友参考一下 一.关于数组的特点 1.在Java中,无论使用数组或集合,都有边界检查。如果越界操作就会得到一个RuntimeException异常。 2.数组只能保存特定类型。数组可以保存原生数据类型,集合则不能。集合不以具体的类型来处理对象,它们将所有对象都按Object类型处理,集

  • 我有一个错误:警告:count():参数必须是实现可计数的数组或对象

  • 如果我不使用双向数据绑定,将替换为则一切正常。那么正确的方式是什么呢?