赞
踩
一、使用场景
当对象内引用对象,改变内部对象属性的时候其他状态管理如@State、@Provide、@Consume等是无法触发更新的。同样,在数组内如果有对象,改变对象的属性也是无法更新的。在这种情况下就可以采用@Observed和@ObjectLink装饰器了。
二、使用方式
在我们需要监控的对象组件使用@Observed装饰,将需要变更的地方抽取出来作为一个新的组件,新组件内部引用对象使用@ObjectLink装饰。
例如, 在案例代码 这个基础上,我们需要在点击任务完成的时候,修改任务列表卡片的文字颜色,并中划线。这就涉及到了修改任务数组中Task对象的属性,需要更新UI。就需要@Observed和@ObjectLink结合使用。
show code (在案例代码基础上做处理)
- //需要监控的组件使用@Observed装饰
- @Observed
- class Task {
- static id: number = 1
- name:string = '任务名称'+Task.id++
- finished:boolean = false
- }
抽离之前任务列表的item为一个新组件
- @Component
- struct TaskItem {
-
- //接收父组件中传递的task,使用@ObjectLink装饰
- @ObjectLink task: Task
-
- //父组件中处理数据更新的方法
- handTasks: () => void
-
- build() {
- Row() {
- if (this.task.finished) {
- Text(this.task.name)
- .tasksuccessed()
- } else {
- Text(this.task.name)
- }
-
- Checkbox()
- .select(this.task.finished)
- .onChange(value => {
- this.task.finished = value
- console.log('任务状态' + value + '')
- this.handTasks()
- })
- }
- .card()
- .justifyContent(FlexAlign.SpaceBetween)
- }
- }
- //父组件中的任务列表
- List({ space: 10 }) {
- ForEach(this.tasks, (task: Task, index) => {
- ListItem() {
- //将父组件的渲染交给新组件
- TaskItem({task:task,handTasks:this.handleTaskNumber.bind(this)})
- }
- .swipeAction({ end: this.deleteButton(index) })
- }, item => '' + item.name)
- }
其中,需要注意的第一点,传递父组件的方法时,传递的是this.handleTaskNumber没有()。如果传递()就表示方法调用了。
需要注意第二点,我们在将父组件方法传递给子组件的时候。如果没有bind(this)处理,默认调用的父组件方法的this就是子组件。所以,我们需要bind(this)永远使用父组件来调用父组件的方法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。