当前位置: 首页 > news >正文

做网站卖资料广告代发平台

做网站卖资料,广告代发平台,来客php在线客服系统官网,莆田网站建设目录 1、概述 2、StorageProp 2.1、观察变化和行为表现 3、StorageLink 3.1、观察变化和行为表现 4、从应用逻辑使用AppStorage和LocalStorage 5、从UI内部使用AppStorage和LocalStorage 6、不建议借助StorageLink的双向同步机制实现事件通知 6.1、推荐的事件通知方式…

目录

1、概述

2、@StorageProp

2.1、观察变化和行为表现 

3.1、观察变化和行为表现

4、从应用逻辑使用AppStorage和LocalStorage

5、从UI内部使用AppStorage和LocalStorage

6、不建议借助@StorageLink的双向同步机制实现事件通知

6.1、推荐的事件通知方式


        AppStorage是应用全局的UI状态存储,是和应用的进程绑定的,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。和AppStorage不同的是,LocalStorage是页面级的,通常应用于页面内的数据共享。而AppStorage是应用级的全局状态共享,还相当于整个应用的“中枢”,持久化数据PersistentStorage和环境变量Environment都是通过和AppStorage中转,才可以和UI交互。

        本文介绍AppStorage使用场景和相关的装饰器:@StorageProp和@StorageLink。

1、概述

        AppStorage是在应用启动的时候会被创建的单例。它的目的是为了提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。AppStorage将在应用运行过程保留其属性。属性通过唯一的键字符串值访问。

        AppStorage可以和UI组件同步,且可以在应用业务逻辑中被访问。

        AppStorage中的属性可以被双向同步,数据可以是存在于本地或远程设备上,并具有不同的功能,比如数据持久化(详见PersistentStorage)。这些数据是通过业务逻辑中实现,与UI解耦,如果希望这些数据在UI中使用,需要用到@StorageProp和@StorageLink。

2、@StorageProp

        在上文中已经提到,如果要建立AppStorage和自定义组件的联系,需要使用@StorageProp和@StorageLink装饰器。使用@StorageProp(key)/@StorageLink(key)装饰组件内的变量,key标识了AppStorage的属性。

        当自定义组件初始化的时候,@StorageProp(key)/@StorageLink(key)装饰的变量会通过给定的key,绑定在AppStorage对应的属性,完成初始化。本地初始化是必要的,因为无法保证AppStorage一定存在给定的key,这取决于应用逻辑,是否在组件初始化之前在AppStorage实例中存入对应的属性。

        @StorageProp(key)是和AppStorage中key对应的属性建立单向数据同步,我们允许本地改变的发生,但是对于@StorageProp,本地的修改永远不会同步回AppStorage中,相反,如果AppStorage给定key的属性发生改变,改变会被同步给@StorageProp,并覆盖掉本地的修改。

  • 从AppStorage的对应属性到组件的状态变量。

    组件本地的修改是允许的,但是AppStorage中给定的属性一旦发生变化,将覆盖本地的修改。

  • 被装饰的变量的初始值必须指定,如果AppStorage实例中不存在属性,则作为初始化默认值,并存入AppStorage中。

  • @StorageProp不支持从父节点初始化,只能AppStorage中key对应的属性初始化,如果没有对应key的话,将使用本地默认值初始化

2.1、观察变化和行为表现 

观察变化

  • 当装饰的数据类型为boolean、string、number类型时,可以观察到数值的变化。
  • 当装饰的数据类型为class或者Object时,可以观察到赋值和属性赋值的变化,即Object.keys(observedObject)返回的所有属性。
  • 当装饰的对象是array时,可以观察到数组添加、删除、更新数组单元的变化。

框架行为

  • 当@StorageProp(key)装饰的数值改变被观察到时,修改不会被同步回AppStorage对应属性键值key的属性中。
  • 当前@StorageProp(key)单向绑定的数据会被修改,即仅限于当前组件的私有成员变量改变,其他的绑定该key的数据不会同步改变。
  • 当@StorageProp(key)装饰的数据本身是状态变量,它的改变虽然不会同步回AppStorage中,但是会引起所属的自定义组件的重新渲染。
  • 当AppStorage中key对应的属性发生改变时,会同步给所有@StorageProp(key)装饰的数据,@StorageProp(key)本地的修改将被覆盖。

        @StorageLink(key)是和AppStorage中key对应的属性建立双向数据同步:

  1. 本地修改发生,该修改会被写回AppStorage中;
  2. AppStorage中的修改发生后,该修改会被同步到所有绑定AppStorage对应key的属性上,包括单向(@StorageProp和通过Prop创建的单向绑定变量)、双向(@StorageLink和通过Link创建的双向绑定变量)变量和其他实例(比如PersistentStorage)。
  • @StorageLink装饰的变量是双向同步的,从AppStorage的对应属性到自定义组件,从自定义组件到AppStorage对应属性。
  • @StorageLink被装饰变量的初始值必须指定,如果AppStorage实例中不存在属性,则作为初始化默认值,并存入AppStorage中。
3.1、观察变化和行为表现

观察变化

  • 当装饰的数据类型为boolean、string、number类型时,可以观察到数值的变化。
  • 当装饰的数据类型为class或者Object时,可以观察到赋值和属性赋值的变化,即Object.keys(observedObject)返回的所有属性。
  • 当装饰的对象是array时,可以观察到数组添加、删除、更新数组单元的变化。

框架行为

  1. 当@StorageLink(key)装饰的数值改变被观察到时,修改将被同步回AppStorage对应属性键值key的属性中。
  2. AppStorage中属性键值key对应的数据一旦改变,属性键值key绑定的所有的数据(包括双向@StorageLink和单向@StorageProp)都将同步修改;
  3. 当@StorageLink(key)装饰的数据本身是状态变量,它的改变不仅仅会同步回AppStorage中,还会引起所属的自定义组件的重新渲染。

4、从应用逻辑使用AppStorage和LocalStorage

        AppStorage是单例,它的所有API都是静态的,使用方法类似于LocalStorage对应的非静态方法。

AppStorage.SetOrCreate('PropA', 47);let storage: LocalStorage = new LocalStorage({ 'PropA': 17 });
let propA: number = AppStorage.Get('PropA') // propA in AppStorage == 47, propA in LocalStorage == 17
var link1: SubscribedAbstractProperty<number> = AppStorage.Link('PropA'); // link1.get() == 47
var link2: SubscribedAbstractProperty<number> = AppStorage.Link('PropA'); // link2.get() == 47
var prop: SubscribedAbstractProperty<number> = AppStorage.Prop('PropA'); // prop.get() == 47link1.set(48); // two-way sync: link1.get() == link2.get() == prop.get() == 48
prop.set(1); // one-way sync: prop.get() == 1; but link1.get() == link2.get() == 48
link1.set(49); // two-way sync: link1.get() == link2.get() == prop.get() == 49storage.get('PropA') // == 17 
storage.set('PropA', 101);
storage.get('PropA') // == 101AppStorage.Get('PropA') // == 49
link1.get() // == 49
link2.get() // == 49
prop.get() // == 49

5、从UI内部使用AppStorage和LocalStorage

        @StorageLink变量装饰器与AppStorage配合使用,正如@LocalStorageLink与LocalStorage配合使用一样。此装饰器使用AppStorage中的属性创建双向数据同步。

AppStorage.SetOrCreate('PropA', 47);
let appStorage = new LocalStorage({ 'PropA': 48 });/*** 从UI内部使用AppStorage和LocalStorage*/
@Entry(appStorage)
@Component
struct AppStorageDemo1Page {@StorageLink('PropA') storeLink: number = 1;@LocalStorageLink('PropA') localStoreLink: number = 1;build() {Column({ space: 20 }) {Text(`From AppStorage ${this.storeLink}`).onClick(() => this.storeLink += 1)Text(`From LocalStorage ${this.localStoreLink}`).onClick(() => {this.localStoreLink += 1;})}.margin({top: 48})}
}

        运行结果如下:

6、不建议借助@StorageLink的双向同步机制实现事件通知

        不建议开发者使用@StorageLink和AppStorage的双向同步的机制来实现事件通知,AppStorage是和UI相关的数据存储,改变会带来UI的刷新,相对于一般的事件通知,UI刷新的成本较大。

        TapImage中的点击事件,会触发AppStorage中tapIndex对应属性的改变。因为@StorageLink是双向同步,修改会同步回AppStorage中,所以,所有绑定AppStorage的tapIndex自定义组件都会被通知UI刷新。UI刷新带来的成本是巨大的,因此不建议开发者使用此方式来实现基本的事件通知功能。


class ViewData {title: string;uri: Resource;color: Color = Color.Black;constructor(title: string, uri: Resource) {this.title = title;this.uri = uri}
}/*** 事件通知的反例* 不建议借助@StorageLink的双向同步机制实现事件通知*/
@Entry
@Component
struct AppStorageDemo2Page {dataList: Array<ViewData> = [new ViewData('flower', $r('app.media.icon')),new ViewData('OMG', $r('app.media.icon')),new ViewData('OMG', $r('app.media.icon'))]scroller: Scroller = new Scroller()build() {Column() {Grid(this.scroller) {ForEach(this.dataList, (item: ViewData, index?: number) => {GridItem() {TapImage({uri: item.uri,index: index})}.aspectRatio(1)}, (item: ViewData, index?: number) => {return JSON.stringify(item) + index;})}.columnsTemplate('1fr 1fr')}}
}/*** TapImage中的点击事件,会触发AppStorage中tapIndex对应属性的改变。* 因为@StorageLink是双向同步,修改会同步回AppStorage中,所以,* 所有绑定AppStorage的tapIndex自定义组件都会被通知UI刷新。* UI刷新带来的成本是巨大的,因此不建议开发者使用此方式来实现基本的事件通知功能。*/
@Component
export struct TapImage {@StorageLink('tapIndex') @Watch('onTapIndexChange') tapIndex: number = -1;@State tapColor: Color = Color.Black;private index: number = 0;private uri: Resource = {id: 0,type: 0,moduleName: "",bundleName: ""};// 判断是否被选中onTapIndexChange() {if (this.tapIndex >= 0 && this.index === this.tapIndex) {console.info(`tapindex: ${this.tapIndex}, index: ${this.index}, red`)this.tapColor = Color.Red;} else {console.info(`tapindex: ${this.tapIndex}, index: ${this.index}, black`)this.tapColor = Color.Black;}}build() {Column() {Image(this.uri).objectFit(ImageFit.Cover).onClick(() => {this.tapIndex = this.index;}).border({ width: 5, style: BorderStyle.Dotted, color: this.tapColor })}}
}
6.1、推荐的事件通知方式

        可以使用emit订阅某个事件并接收事件回调,可以减少开销,增强代码的可读性。


import emitter from '@ohos.events.emitter';let Demo3NextID: number = 0;class Demo2ViewData {title: string;uri: Resource;color: Color = Color.Black;id: number;constructor(title: string, uri: Resource) {this.title = title;this.uri = urithis.id = Demo3NextID++;}
}/*** 基于事件的方式触发UI更新(推荐)*/
@Entry
@Component
struct AppStorageDemo3Page {dataList: Array<Demo2ViewData> = [new Demo2ViewData('flower', $r('app.media.icon')),new Demo2ViewData('OMG', $r('app.media.icon')),new Demo2ViewData('OMG', $r('app.media.icon'))]scroller: Scroller = new Scroller()private preIndex: number = -1build() {Column() {Grid(this.scroller) {ForEach(this.dataList, (item: Demo2ViewData) => {GridItem() {Demo2TapImage({uri: item.uri,index: item.id})}.aspectRatio(1).onClick(() => {if (this.preIndex === item.id) {return}let innerEvent: emitter.InnerEvent = { eventId: item.id }// 选中态:黑变红let eventData: emitter.EventData = {data: {"colorTag": 1}}emitter.emit(innerEvent, eventData)if (this.preIndex != -1) {console.info(`preIndex: ${this.preIndex}, index: ${item.id}, black`)let innerEvent: emitter.InnerEvent = { eventId: this.preIndex }// 取消选中态:红变黑let eventData: emitter.EventData = {data: {"colorTag": 0}}emitter.emit(innerEvent, eventData)}this.preIndex = item.id})}, (item: Demo2ViewData) => JSON.stringify(item))}.columnsTemplate('1fr 1fr')}}
}@Componentstruct Demo2TapImage {@State tapColor: Color = Color.Black;private index: number = 0;private uri: Resource = {id: 0,type: 0,moduleName: "",bundleName: ""};onTapIndexChange(colorTag: emitter.EventData) {if (colorTag.data != null) {this.tapColor = colorTag.data.colorTag ? Color.Red : Color.Black}}aboutToAppear() {//定义事件IDlet innerEvent: emitter.InnerEvent = { eventId: this.index }//注册事件emitter.on(innerEvent, data => {this.onTapIndexChange(data)})}build() {Column() {Image(this.uri).objectFit(ImageFit.Cover).border({ width: 5, style: BorderStyle.Dotted, color: this.tapColor })}}
}

        运行结果如下:

        当用户点击其中一个图标时会展示不同颜色的边框,同时取消上一个选择的图标的红色边框 ,该推荐demo使用基于事件的通知方式触发事件通知,减少UI刷新通知的方式所带来的性能开销。

http://www.dinnco.com/news/14506.html

相关文章:

  • 长春网站建设网泽成seo网站排名
  • Wordpress 日主题优化关键词哪家好
  • 做粉丝网站会侵权吗网站建设与管理
  • 物流公司网站建设方案新品上市怎么做宣传推广
  • 网站申请百中搜优化
  • 做母婴产品哪个网站做的好西安做网站的网络公司
  • 怎么查有做网站的公司大丰seo排名
  • 南宁seo网站排名优化公司网上推广产品哪个网好
  • 南宁商城网站建设哪些平台可以发布软文
  • 网站建设通知书阿里大数据平台
  • 软文营销网站方象科技的服务范围
  • 网站开发 论文网址查询服务中心
  • 网站群建设方案网站seo站长工具
  • 国内做赌博网站风险大吗站群seo
  • 北京疫情防控最新规定南宁seo内部优化
  • 怎么做有图有声的网站代做百度收录排名
  • 分类网站建设方案学生个人网页制作成品
  • 安徽网站优化怎么做郑州做网站最好的公司
  • 百度做网站找谁网站建设选亿企网络
  • 什么网站做视频最赚钱如何做电商
  • 网站建设优化公司呼和浩特一键建站
  • 南宁自己的网站百度数据研究中心官网
  • 做投标网站条件宁波seo网络优化公司
  • 防水堵漏公司做网站效果怎样百度经验悬赏令
  • 易龙天做的网站怎么样百度正版下载恢复百度
  • 我们的优势的网站浏览器搜索引擎大全
  • 购物网站建设方案最新推广注册app拿佣金
  • 电子网站建设设计太原今日新闻最新头条
  • 沭阳住房城乡建设局网站最近三天的新闻大事小学生
  • 牛皮纸东莞网站建设技术支持线上推广引流渠道