HarmonyOS 鸿蒙Next 子组件里修改 ObjectLink 的状态无法同步回父组件?我修改了某个todo的 complete,但是父组件 this.arrA.filter(i => i.complete).length 的数据没有变化

发布于 1周前 作者 nodeper 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 子组件里修改 ObjectLink 的状态无法同步回父组件?我修改了某个todo的 complete,但是父组件 this.arrA.filter(i => i.complete).length 的数据没有变化 子组件里修改 ObjectLink 的状态,好像无法同步回父组件?我修改了某个todo的 complete,但是父组件 this.arrA.filter(i => i.complete).length 的数据没有变化;

但是通过 push 修改以后,this.arrA.filter(i => i.complete).length 的UI 可以看到被更新

图片

import Demo from '../components/Demo'
import NavBack from '../components/NavBack'

@Component
struct TodoItemView {
  @ObjectLink todoItem: TodoItem;

  build() {
    Row() {
      Text(this.todoItem.id.toString() + '. ')

      Checkbox()
        .select(this.todoItem.complete)
        .shape(CheckBoxShape.CIRCLE)
        .onClick(() => {
          this.todoItem.toggle();
        })
      Text(this.todoItem.name)
    }.width('100%')
  }
}

@Entry
@Component
struct ObservedAndObjectLink {
  @State arrA: TodoItem[] = [new TodoItem('eat'), new TodoItem('run')];

  @Builder
  objectBuilder() {
    Text('objectBuilder')
  }

  @LocalBuilder
  arrayBuilder() {
    Column() {
      ForEach(this.arrA,
        (item: TodoItem) => {
          TodoItemView({
            todoItem: item
          })

        },
        (item: TodoItem): string => item.id.toString()
      )

      Text(this.arrA.filter(i => i.complete).length.toString() + '已完成')
      Button('增加').onClick(() => {
        this.arrA.push(new TodoItem('sleep'))
      })
    }

  }

  build() {
    Column() {
      NavBack()
      Demo({
        title: '嵌套对象',
        slotBuilderParam: () => {
          this.objectBuilder()
        }
      })

      Demo({
        title: '对象数组',
        slotBuilderParam: this.arrayBuilder
      })


    }.alignItems(HorizontalAlign.Start)
    .height('100%')
    .width('100%')
  }
}

let NextID: number = 1;

@Observed
class TodoItem {
  public id: number;
  public name: string;
  complete: boolean;

  constructor(name: string) {
    this.id = NextID++;
    this.name = name;
    this.complete = false;
  }

  toggle() {
    this.complete = !this.complete;
  }
}

更多关于HarmonyOS 鸿蒙Next 子组件里修改 ObjectLink 的状态无法同步回父组件?我修改了某个todo的 complete,但是父组件 this.arrA.filter(i => i.complete).length 的数据没有变化的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

数组做为状态变量时,数组中的对象的属性发生变化时ui不能刷新。数组只有添加对象删除对象,对某个对象赋值或对这个数组赋值才会刷新ui。所以你这个可以尝试对传入的todoitem重新赋值,

更多关于HarmonyOS 鸿蒙Next 子组件里修改 ObjectLink 的状态无法同步回父组件?我修改了某个todo的 complete,但是父组件 this.arrA.filter(i => i.complete).length 的数据没有变化的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


@Component
struct TodoItemView {
  todoItem: TodoItem = new TodoItem('');

  build() {
    Row() {
      Text(this.todoItem.id.toString() + '. ')

      Checkbox()
        .select(this.todoItem.complete)
        .shape(CheckBoxShape.CIRCLE)
        .onClick(() => {
          this.todoItem.toggle();
        })
      Text(this.todoItem.name)
    }.width('100%')
  }
}

@Component
struct Demo {
  private title: string = ''
  @BuilderParam slotBuilderParam: () => void

  build() {
    Row() {
      Text(this.title)

      this.slotBuilderParam()
    }.width('100%')
  }
}

@Entry
@Component
struct ObservedAndObjectLink {
  dataList: TodoItemList = new TodoItemList();

  aboutToAppear() {
    this.dataList.datas.push(...[new TodoItem('eat'), new TodoItem('run')]);
  }

  @Builder
  objectBuilder() {
    Text('objectBuilder')
  }

  @LocalBuilder
  arrayBuilder() {
    Column() {
      ForEach(this.dataList.datas,
        (item: TodoItem) => {
          TodoItemView({
            todoItem: item
          })
        },
        (item: TodoItem): string => item.id.toString()
      )

      Text(this.dataList.datas.filter(i => i.complete).length.toString() + '已完成')
      Button('增加').onClick(() => {
        this.dataList.datas.push(new TodoItem('sleep'))
      })
    }

  }

  build() {
    Column() {
      Demo({
        title: '嵌套对象',
        slotBuilderParam: () => {
          this.objectBuilder()
        }
      })

      Demo({
        title: '对象数组',
        slotBuilderParam: this.arrayBuilder
      })


    }.alignItems(HorizontalAlign.Start)
    .height('100%')
    .width('100%')
  }
}

let NextID: number = 1;

@ObservedV2
class TodoItem {
  @Trace id: number;
  @Trace name: string;
  @Trace complete: boolean;

  constructor(name: string) {
    this.id = NextID++;
    this.name = name;
    this.complete = false;
  }

  toggle() {
    this.complete = !this.complete;
  }
}

//xxx.ets
@Observed
export class ObservedArray<T> extends Array<T> {
  constructor(args?: T[]) {
    if (args instanceof Array) {
      super(...args);
    } else {
      super();
    }
  }
}

@ObservedV2
export class TodoItemList {
  @Trace datas: ObservedArray<TodoItem> = new ObservedArray();
}

在HarmonyOS鸿蒙系统中,如果你在子组件中修改了ObjectLink的状态,但父组件未能同步更新,这通常是因为数据绑定的机制或状态更新方式存在问题。

确保你遵循了以下步骤:

  1. 数据绑定正确:检查ObjectLink是否正确绑定到父组件的数据对象。确保在父组件中传递的数据对象是通过@link或类似机制正确传递给子组件的。

  2. 状态更新通知:在子组件中修改complete状态时,确保触发了状态更新的通知。鸿蒙系统中,状态变化通常需要通过特定的机制(如数据模型的notifyPropertyChanged方法)来通知系统。

  3. 父组件监听:父组件需要正确监听子组件状态的变化。如果使用的是ObjectLink,父组件应该能够自动监听到变化,除非有特定的逻辑阻止了更新。

  4. 组件生命周期:检查组件的生命周期管理,确保在修改状态时组件仍然活跃且未处于销毁状态。

如果以上步骤均无误,但问题依旧存在,可能是系统或框架层面的bug。此时,可以尝试简化代码,逐步排查问题,或查阅最新的鸿蒙开发文档以获取更多信息。

如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html

回到顶部