HarmonyOS鸿蒙Next中AppStorage.setOrCreate设置的值如何更新?

HarmonyOS鸿蒙Next中AppStorage.setOrCreate设置的值如何更新? 我这里使用了AppStorage.setOrCreate 设置了一个songList 当前页面会显示这个list中的一些元素,但是这个songList是另一个文件里导入的Const修饰的list

这里想请教一下各位大佬如何更新这个list实现页面也同步更新? 如果不能修改,那么我应该用什么方式实现这个目的?有没有其他的数据结构可以实现?

  aboutToAppear() {
    let context = getContext(this) as common.Context; // 请确保getContext(this)返回结果为UIAbilityContext
    const documentSelectOptions = new picker.DocumentSelectOptions();
    // 选择文档的最大数目(可选)
    documentSelectOptions.maxSelectNumber = 100;
    documentSelectOptions.mergeMode = 1;
    documentSelectOptions.selectMode = 0
    // 指定选择的文件或者目录路径(可选)
    // documentSelectOptions.defaultFilePathUri = "file://docs/storage/Users/currentUser/test";
    // 选择文件的后缀类型['后缀类型描述|后缀类型'](可选) 若选择项存在多个后缀名,则每一个后缀名之间用英文逗号进行分隔(可选),后缀类型名不能超过100,选择所有文件:'所有文件(*.*)|.*';
    documentSelectOptions.fileSuffixFilters = ['音乐(.mp3, .flac, .wav, .ogg)|.mp3,.flac,.wav,.ogg'];
    //选择是否对指定文件或目录授权,true为授权,当为true时,defaultFilePathUri为必选参数,拉起文管授权界面;false为非授权,拉起常规文管界面(可选)
    // documentSelectOptions.authMode = true;
    let uris: Array<string> = [];
    // 创建文件选择器实例
    const documentViewPicker = new picker.DocumentViewPicker(context);
    documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => {
      //文件选择成功后,返回被选中文档的uri结果集。
      uris = documentSelectResult;
      console.info('documentViewPicker.select to file succeed and uris are:' + uris);
    })
    AppStorage.setOrCreate('songList', songList);
    MediaService.getInstance();
    this.breakpointSystem.register();
  }

  const songList: SongItem[] = [
  { id: 1, title: 'Dream It Possible', singer: 'Delacey', mark: $rawfile('media/ic_useless/ic_vip.svg'),
    label: $rawfile('media/ic_ablum_avatar/ic_dream.png'), src: 'Delacey - Dream It Possible.flac', index:0,
    lyric: 'lrcfiles/DreamItPossible.lrc' }]

更多关于HarmonyOS鸿蒙Next中AppStorage.setOrCreate设置的值如何更新?的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

请参考如下Navigation和AppStorage的例子:

场景

Navigation在分栏模式下,需要实现点击子页“放大”按钮,实现子页放大到全屏的功能。

背景知识

  • Navigation组件的分栏模式由mode属性控制,包括单栏(Stack)、分栏(Split)和自适应(Auto)三个属性。可通过状态管理实现动态切换mode属性的单栏与分栏模式,实现子页的放大效果。
  • AppStorage是在应用启动的时候会被创建的单例。它的目的是为了提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。AppStorage将在应用运行过程保留其属性。属性通过唯一的键字符串值访问。通过**@StorageLink**可以和AppStorage中key对应的属性建立双向数据同步:
    1. 本地修改发生,该修改会被写回AppStorage中。
    2. AppStorage中的修改发生后,该修改会被同步到所有绑定AppStorage对应key的属性上,包括单向(@StorageProp和通过Prop创建的单向绑定变量)、双向(@StorageLink和通过Link创建的双向绑定变量)变量和其他实例(比如PersistentStorage)。

解决方案

  • 通过@StorageLink创建状态管理变量isSplit控制Navigation组件的mode属性。
  • 通过AppStorage.set方法修改状态管理变量isSplit值,从而控制Navigation组件的mode属性,并刷新UI。

更多关于HarmonyOS鸿蒙Next中AppStorage.setOrCreate设置的值如何更新?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,AppStorage.setOrCreate用于设置或创建全局状态值。要更新该值,直接再次调用AppStorage.setOrCreate并传入新的值即可。系统会自动更新存储中的对应值,所有依赖该值的组件也会同步刷新。例如,AppStorage.setOrCreate('key', newValue)会将key对应的值更新为newValue

在HarmonyOS Next中,AppStorage.setOrCreate设置的值要实现响应式更新,需要注意以下几点:

  1. 对于const修饰的数组,直接修改其内容不会触发AppStorage的更新机制。AppStorage的响应式更新需要重新赋值整个对象。

  2. 建议改用@Observed装饰器和@Track装饰器来实现响应式更新:

@Observed
class SongList {
  @Track items: SongItem[] = [...]; // 初始数据
}

const observedSongList = new SongList();
AppStorage.setOrCreate('songList', observedSongList);
  1. 更新数据时应使用新数组替换旧数组:
// 更新方式
const newList = [...observedSongList.items, newItem];
observedSongList.items = newList;
  1. 如果必须使用const数组,可以考虑:
  • 改用@State@Link装饰的变量
  • 使用深拷贝创建新数组后重新赋值
  1. 对于你的具体场景,建议将songList改为可观察对象,并在修改时创建新数组赋值,这样才能确保UI同步更新。
回到顶部