一、使用場景
當對象內引用對象,改變內部對象屬性的時候其他狀態管理如@State、@Provide、@Consume等是無法觸發更新的。同樣,在數組內如果有對象,改變對象的屬性也是無法更新的。在這種情況下就可以采用@Observed和@ObjectLink裝飾器了。
二、使用方式
在我們需要監控的對象組件使用@Observed裝飾,將需要變更的地方抽取出來作為一個新的組件,新組件內部引用對象使用@ObjectLink裝飾。
例如,?在案例代碼?這個基礎上,我們需要在點擊任務完成的時候,修改任務列表卡片的文字顏色,并中劃線。這就涉及到了修改任務數組中Task對象的屬性,需要更新UI。就需要@Observed和@ObjectLink結合使用。
?show code (在案例代碼基礎上做處理)
//需要監控的組件使用@Observed裝飾
@Observed
class Task {static id: number = 1name:string = '任務名稱'+Task.id++finished:boolean = false
}
抽離之前任務列表的item為一個新組件
@Component
struct TaskItem {//接收父組件中傳遞的task,使用@ObjectLink裝飾@ObjectLink task: Task//父組件中處理數據更新的方法handTasks: () => voidbuild() {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 = valueconsole.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)永遠使用父組件來調用父組件的方法。