@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变革
媒介
为什么要有@Observed装饰器和@ObjectLink装饰器?
在@Prop,@Link,@Provide与@Consume这几个装饰器仅能观察到第一层的变革,在实际应用开发中,应用会根据开发必要,封装本身的数据模子。对于多层嵌套的情况,比如二维数组,或者数组项class,或者class的属性是class,他们的第二层的属性变革是无法观察到的。这就引出了@Observed/@ObjectLink装饰器的作用。
概述
@ObjectLink和@Observed类装饰器用于在涉及嵌套对象或数组的场景中举行双向数据同步:
●被@Observed装饰的类,可以被观察到属性的变革;
●子组件中@ObjectLink装饰器装饰的状态变量用于吸收@Observed装饰的类的实例,和父组件中对应的状态变量创建双向数据绑定。这个实例可以是数组中的被@Observed装饰的项,或者是class object中的属性,这个属性同样也必要被@Observed装饰。
●单独使用@Observed是没有任何作用的,必要搭配@ObjectLink或者@Prop使用。
注意:
使用@Observed装饰class会改变class原始的原型链,@Observed和其他类装饰器装饰同一个class可能会带来问题。
@ObjectLink装饰器不能在@Entry装饰的自界说组件中使用。
装饰器阐明
@ObjectLink装饰的变量不能被赋值,假如要使用赋值操纵,可以使用@Prop。
●@Prop装饰的变量和数据源的关系是是单向同步,@Prop装饰的变量在本地拷贝了数据源,所以它允许本地更改,假如父组件中的数据源有更新,@Prop装饰的变量本地的修改将被覆盖;
●@ObjectLink装饰的变量和数据源的关系是双向同步,@ObjectLink装饰的变量相当于指向数据源的指针。克制对@ObjectLink装饰的变量赋值,假如一旦发生@ObjectLink装饰的变量的赋值,则同步链将被打断。因为@ObjectLink装饰的变量通过数据源(Object)引用来初始化。对于实现双向数据同步的@ObjectLink,赋值相当于更新父组件中的数组项或者class的属性,TypeScript/JavaScript不能实现,会发生运行时报错。
框架举动
●初始渲染:
●@Observed装饰的class的实例会被不透明的代理对象包装,代理了class上的属性的setter和getter方法
●子组件中@ObjectLink装饰的从父组件初始化,吸收被@Observed装饰的class的实例,@ObjectLink的包装类会将本身注册给@Observed class。
●属性更新:当@Observed装饰的class属性改变时,会走到代理的setter和getter,然后遍历依靠它的@ObjectLink包装类,通知数据更新。
示例:
嵌套对象和数组
- @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
- }
- }
- @Component
- struct Child{
- @ObjectLink p:Person
- build() {
- Column(){
- Text(`${this.p.name}:${this.p.age}`)
- }
- }
- }
- @Entry
- @Component
- struct Parent{
- @State p:Person=new Person('Tom',21,new Person('Rose',18))
- @State gfs:Person[]=[new Person('汤姆',16),new Person('路西',18)]
- build() {
- Column(){
- Child({p:this.p.gf})
- .onClick(()=>this.p.gf.age++)
- Text('-------------------')
- ForEach(
- this.gfs,
- p=>{
- Child({p:p}).onClick(()=>this.p.age++)
- }
- )
- }
- }
- }
复制代码 在子组件中给@ObjectLink装饰的变量赋值是不允许的。
- @Observed
- class ClassA {
- public c: number = 0;
- constructor(c: number) {
- this.c = c;
- }
- }
- @Component
- struct ObjectLinkChild {
- @ObjectLink testNum: ClassA;
- build() {
- Text(`ObjectLinkChild testNum ${this.testNum.c}`)
- .onClick(() => {
- // ObjectLink不能被赋值 这是不允许的,对于实现双向数据同步的@ObjectLink,赋值相当于要更新父组件中的数组项或者class的属性,这个对于 TypeScript/JavaScript是不能实现的。框架对于这种行为会发生运行时报错。
- this.testNum = new ClassA(47);
- // 可以对ObjectLink装饰对象的属性赋值
- //this.testNum.c = 47;
- })
- }
- }
- @Entry
- @Component
- struct Parent {
- @State testNum: ClassA[] = [new ClassA(1)];
- build() {
- Column() {
- Text(`Parent testNum ${this.testNum[0].c}`)
- .onClick(() => {
- this.testNum[0].c += 1;
- })
- ObjectLinkChild({ testNum: this.testNum[0] })
- }
- }
- }
复制代码 @Prop与@ObjectLink的差别
@ObjectLink装饰的变量是对数据源的引用
代码示例:
@Prop装饰变量时会举行深拷贝
假如用@Prop替代@ObjectLink。点击第一个click handler,UI革新正常。但是点击第二个onClick变乱,@Prop 对变量做了一个本地拷贝,CounterComp的第一个Text并不会革新。
this.value.subCounter和this.subValue并不是同一个对象。所以this.value.subCounter的改变,并没有改变this.subValue的拷贝对象,Text(
this.subValue.counter: ${this.subValue.counter}
)不会革新。
代码示例:
- @Component
- struct CounterComp {
- @Prop value: ParentCounter = new ParentCounter(0);
- @Prop subValue: SubCounter = new SubCounter(0);
- build() {
- Column({ space: 10 }) {
- Text(`this.subValue.counter: ${this.subValue.counter}`)
- .fontSize(20)
- .onClick(() => {
- // 1st click handler
- this.subValue.counter += 7;
- })
- Text(`this.value.counter:increase 7 `)
- .fontSize(20)
- .onClick(() => {
- // 2nd click handler
- this.value.incrSubCounter(7);
- })
- Divider().height(2)
- }
- }
- }
复制代码 总结:
每个装饰器都有本身可以观察的能力,并不是全部的改变都可以被观察到,只有可以被观察到的变革才会举行UI更新。@Observed装饰器可以观察到嵌套对象的属性变革,其他装饰器仅能观察到第二层的变革。
●@ObjectLink和@Observed类装饰器用于在涉及嵌套对象或数组的场景中举行双向数据同步:
●被@Observed装饰的类,可以被观察到属性的变革;
●子组件中@ObjectLink装饰器装饰的状态变量用于吸收@Observed装饰的类的实例,和父组件中对应的状态变量创建双向数据绑定。
单独使用@Observed是没有任何作用的,必要搭配@ObjectLink或者@Prop使用。
@ObjectLink装饰的变量和数据源的关系是双向同步,@ObjectLink装饰的变量相当于指向数据源的指针。克制对@ObjectLink装饰的变量赋值,假如一旦发生@ObjectLink装饰的变量的赋值,则同步链将被打断。
@Prop与@ObjectLink的差别:
@ObjectLink装饰的变量是对数据源的引用
@Prop装饰变量时会举行深拷贝
写在最后
总的来说,华为鸿蒙不再兼容安卓,对中年步调员来说是一个寻衅,也是一个机会。随着鸿蒙的不断发展以及国家的大力支持,将来鸿蒙职位肯定会迎来一个大的发作,只有积极应对变革,不断学习和提升本身,我们才气在这个变革的期间中立于不败之地。
●假如你觉得这篇内容对你还蛮有资助,我想约请你帮我两个小忙:
●点赞,转发,有你们的 『点赞和批评』,才是我创造的动力。
●关注小编,同时可以等待后续文章ing ,不定期分享原创知识。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |