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

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():参数必须是实现可计数的数组或对象

  • 本文向大家介绍Nuxt.js 数据双向绑定的实现,包括了Nuxt.js 数据双向绑定的实现的使用技巧和注意事项,需要的朋友参考一下 假定我们有一个需求,一开始通过mounted()将一个字符串渲染在页面上,但是我们经过操作后修改了数据并且需要将得到的结果重新异步渲染到页面中去,而不是跳转刷新页面来重新渲染 首先模板中data()中定义数据,并且要将定义的数据显示出来 然后我们通过methods里的

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

  • 我想从这个HTML中解析数据(CompanyName,Location,jobDescription,...)使用JSoup(java)。我在尝试迭代工作列表时会被卡住 从HTML中提取是我想要迭代并从中提取数据的许多“joblisting”div中的一个。我只是无法处理如何迭代特定的div对象。很抱歉这个问题,但也许有人可以帮助我谁已经知道使用哪一个功能。选择? 文件输入=新文件(“C:/tal