Verwendung von ArkTS @Observed- und @ObjectLink-Zustandsdekoratoren

 Wirkung

Die Dekoratoren @Observed und @ObjectLink werden für die bidirektionale Datensynchronisierung in Szenarien verwendet, in denen verschachtelte Objekte oder Array-Elemente als Objekte verwendet werden.

Verwendung von Status

1. Verschachtelte Objekte

Wir setzen die übergeordnete Klasse auf den @Observed-Status. Zu diesem Zeitpunkt sollte das untergeordnete Element @ObjectLink festlegen, um die bidirektionale Datenbindung abzuschließen. Daher erstellen wir eine Komponente und lassen den Status zu einer Variablen werden, um den Status des Attributs zu vervollständigen .

@Observed
class Person{
  name: string
  age: number
  gf: Person

  constructor(name:string, age: number, gf?: Person) {
    this.name = name
    this.age = age
    this.gf = gf
  }
}

@Entry
@Component
struct Parent {
  @State p: Person = new Person('zhangsan',21,new Person('lisi',18))
  build() {
    Row() {
      Column() {
        Child({p:this.p.gf})
          .onClick(()=>this.p.gf.age++)
      }
      .width('100%')
    }
    .height('100%')
  }
}

@Component
struct Child{
  @ObjectLink p: Person
  build(){
    Column(){
      Text(`${this.p.name} : ${this.p.age}`)
    }
  }
}

2. Objektelemente im Array

Solange unsere Daten durch die Hände von Child gehen, also die durch @ObjectLink gebundenen Variablen verwenden, löst die Aktualisierung des Variablenstatus direkt die Aktualisierung der Ansicht aus.

@Observed
class Person{
  name: string
  age: number
  gf: Person

  constructor(name:string, age: number, gf?: Person) {
    this.name = name
    this.age = age
    this.gf = gf
  }
}

@Entry
@Component
struct Parent {
  @State p: Person = new Person('zhangsan',21,new Person('lisi',18))
  @State gfs: Person[] = [
  new Person('wangwu',18),new Person('yangliu',19), ]
  build() {
    Row() {
      Column() {
        Child({p:this.p.gf})
          .onClick(()=>this.p.gf.age++)
        Text('===== 列表 =====')
        ForEach(
          this.gfs,
          p=> {
            Child({p:p}).onClick(()=>p.age++)
          }
        )
      }
      .width('100%')
    }
    .height('100%')
  }
}

@Component
struct Child{
  @ObjectLink p: Person
  build(){
    Column(){
      Text(`${this.p.name} : ${this.p.age}`)
    }
  }
}

 Fallüberprüfung der Aufgabenstatistik

Lassen Sie uns diese beiden Zustände im Fall der Aufgabenstatistik verwenden.

Wir möchten nun einen Effekt erzielen, der darin besteht, die erledigten Aufgaben grau darzustellen und einen Durchstreichungseffekt hinzuzufügen.

// 任务完成样式
@Extend(Text) function finishedTask(){
  .decoration({type:TextDecorationType.LineThrough})
  .fontColor('#b1b2b1')
}
  
Row(){
   if(item.finished){
       Text(item.name)
       .finishedTask()
        }else{
       Text(item.name)
        }
      Checkbox()
      .select(item.finished)
      .onChange(val=>{
     item.finished = val
    // 通过过滤方法 更新已完成的任务数量
      this.handleTaskChange()
    })
}

Wir beurteilten den Status jeder Aufgabe anhand der Entscheidung, welchen Effekt wir verwenden wollten, und stellten fest, dass unser Effekt nicht erreicht werden konnte. Da foreach das Array durchläuft, entspricht dies einer Änderung der Eigenschaften der Array-Elemente. Es kommt vor, dass die Eigenschaft, die wir ändern möchten, ein Objekt ist, sodass unsere Änderung keine Aktualisierung der Ansicht auslöst. Daher sollten wir @Observed verwenden und @ObjectLink gibt an, es abzuschließen. In diesem Fall. 

Fügen wir also dem Objekt des verschachtelten Arrays, das implementiert werden muss, einen Status hinzu.

Wir fügen den @Observed-Status zur ursprünglichen Klassenaufgabe hinzu und fügen den @ObjectLink-Status zum Element in der Zeile hinzu, das durch die Kapselungsschleife generiert wurde. Da es in unserer Komponente keine Funktion zur Statusänderung gibt, entfernen wir sie zuerst und vervollständigen den Stil Modifikation zuerst.



@Observed
class Task{
  static id: number = 1
  // 任务名称
  name: string = `任务${Task.id++}`
  // 任务状态: 是否完成
  finished: boolean = false
}

// 统计的卡片样式
@Styles function card(){
  .width('95%')
  .padding(20)
  .backgroundColor(Color.White)
  .borderRadius(15)
  .shadow({radius: 6,color: '#1f0000',offsetX:2,offsetY:4})
}

// 任务完成样式
@Extend(Text) function finishedTask(){
  .decoration({type:TextDecorationType.LineThrough})
  .fontColor('#b1b2b1')
}


// 任务统计信息
class StaticInfo{
  totalTask: number = 0
  finishTask: number = 0
}

@Entry
@Component
struct PropPage {
  // 统计信息
  @Provide stat: StaticInfo = new StaticInfo()

  build() {
      Column({space:10}) {
        // 1.任务进度卡片
        TaskStatistics()
        // 2.任务列表
        TaskList();
      }
      .width('100%')
      .height('100%')
      .backgroundColor('#f1f2f3')
  }

}


@Component
struct TaskStatistics {

  @Consume stat: StaticInfo

  build(){
    Row(){
      Text("任务进度")
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
      Stack(){
        Progress({
          value:this.stat.finishTask,
          total:this.stat.totalTask,
          type:ProgressType.Ring
        })
          .width(100)
        Row(){
          Text(this.stat.finishTask.toString())
            .fontSize(24)
            .fontColor('#36d')
          Text(' / ' +this.stat.totalTask.toString())
            .fontSize(24)
        }
      }
    }
    .card()
    .margin({top:20,bottom:10})
    .justifyContent(FlexAlign.SpaceEvenly)
  }
}

@Component
struct TaskList {
  // 任务数量
  @State tasks: Task[] = []
  @Consume stat: StaticInfo
  // 通过过滤方法 更新已完成的任务数量
  handleTaskChange(){
    // 更新任务总数量
    this.stat.totalTask = this.tasks.length
    // 已经完成的任务数量
    this.stat.finishTask = this.tasks.filter(item => item.finished).length
  }
  build(){
      Column(){
        // 2.新增任务按钮
        Button('新增任务')
          .width(200)
          .onClick(()=>{
            // 1.新增任务
            this.tasks.push(new Task())
            // 2.更新任务数组
            this.stat.totalTask = this.tasks.length
          })
        // 3.卡片列表
        List({space:10}){
          ForEach(
            this.tasks,
            (item: Task,index)=>{
              ListItem(){
                TaskItem({item:item})
              }
              .swipeAction({end:this.DeleteButton(index)})
            }
          )
        }
        .width('100%')
        .layoutWeight(1)
        .alignListItem(ListItemAlign.Center)
      }
  }
  @Builder DeleteButton(index: number){
    Button("删除")
      .onClick(()=>{
        this.tasks.splice(index,1)
        this.handleTaskChange()
      })
  }
  }

@Component
struct TaskItem {

  @ObjectLink item: Task
  build(){
    Row(){
      if(this.item.finished){
        Text(this.item.name)
          .finishedTask()
      }else{
        Text(this.item.name)
      }
      Checkbox()
        .select(this.item.finished)
        .onChange(val=>{
          this.item.finished = val
          // 通过过滤方法 更新已完成的任务数量
          // this.handleTaskChange()
        })
    }
    .card()
    .justifyContent(FlexAlign.SpaceBetween)
  }
}

Wir werden feststellen, dass durch Klicken auf unsere Fertig-Prüfung unser Farb- und Durchstreichungsstatus erfolgreich wiedergegeben wird, sodass unsere bidirektionale Bindung des verschachtelten Arrays erfolgreich ist.

Lassen Sie uns nun die Funktionalität vervollständigen und unseren Abschlussstatus aktualisieren.

Methodenübergabe

Wir können Methoden durch Methodenübergabe öffentlich machen.

 

@Component
struct TaskItem {
  @ObjectLink item: Task
  onTaskChange: () => void
  build(){
    Row(){
      if(this.item.finished){
        Text(this.item.name)
          .finishedTask()
      }else{
        Text(this.item.name)
      }
      Checkbox()
        .select(this.item.finished)
        .onChange(val=>{
          this.item.finished = val
          // 通过过滤方法 更新已完成的任务数量
          this.onTaskChange();
        })
    }
    .card()
    .justifyContent(FlexAlign.SpaceBetween)
  }
}

Wir schreiben eine Funktion in die taskItem-Methode und übergeben die Funktion beim Aufruf. Dies entspricht dem Aufruf dieser Methode in taskItem. 

Dann werden wir feststellen, dass es immer noch nicht umgesetzt ist. Weil der Verweis darauf in der untergeordneten Komponente falsch ist.

Wenn die Methode übergeben wird, muss dies bestätigt werden, da sich die Person, die die Methode aufgerufen hat, geändert hat.

Daher müssen wir sicherstellen, dass bei der Übergabe von Methoden der Zeiger dieser Methode nicht geändert werden kann. Zu diesem Zeitpunkt müssen wir eine API verwenden

binden(dies)

Zu diesem Zeitpunkt können wir den Effekt vollständig erkennen. 

Supongo que te gusta

Origin blog.csdn.net/a_strong_pig/article/details/135108012
Recomendado
Clasificación