HarmonyOS鸿蒙Next中请问一下各位大佬@ObservedV2 + @Trace在V1页面上混合使用时,为什么UI没有自动刷新页面又没报错?
HarmonyOS鸿蒙Next中请问一下各位大佬@ObservedV2 + @Trace在V1页面上混合使用时,为什么UI没有自动刷新页面又没报错?
用@ObservedV2+@Trace观察的2个类代码如下:
/**
* 朋友圈用户数据
*/
[@ObservedV2](/user/ObservedV2)
export class FriendMoment {
[@Trace](/user/Trace) id: string; // 唯一id
[@Trace](/user/Trace) userName: string; // 用户名
[@Trace](/user/Trace) avatar: ResourceStr; // 头像
[@Trace](/user/Trace) text: string; // 文字
[@Trace](/user/Trace) image?: ResourceStr; // 发布动态图片
[@Trace](/user/Trace) video?: ResourceStr; // 发布动态视频
constructor(id: string, userName: string, avatar: ResourceStr, text: string, image?: ResourceStr,
video?: ResourceStr) {
this.id = id;
this.userName = userName;
this.avatar = avatar;
this.text = text;
if (image !== undefined) {
this.image = image;
}
;
if (video !== undefined) {
this.video = video;
}
}
}
[@ObservedV2](/user/ObservedV2)
export class CommentData extends BasicDataSource<FriendMoment> {
// 懒加载数据
[@Trace](/user/Trace) private comments: Array<FriendMoment> = [];
// TODO:知识点:获取懒加载数据源的数据长度
totalCount(): number {
return this.comments.length;
}
// 获取指定数据项
getData(index: number): FriendMoment {
return this.comments[index];
}
// TODO:知识点:存储数据到懒加载数据源中
pushData(data: FriendMoment): void {
this.comments.push(data);
// 在数组头部添加数据
this.notifyDataAdd(this.comments.length - 1);
}
addDataFirst(data: FriendMoment): void {
this.comments.unshift(data);
// 在数组头部添加数据
this.notifyDataAdd(0);
}
}
// 从云数据库加载数据
export async function LoadUserPostData(): Promise<CommentData> {
let commentList: CommentData = new CommentData();
let result = await DBUtil.queryAllPost()
result.forEach(element => {
if(element.id != undefined && element.nickName != undefined && element.avatar != undefined && element.text != undefined && element.postImage){
let avatarBuf = buffer.from(element.avatar);
let avatarBase64Str = avatarBuf.toString('base64')
let postPhotoBuf = buffer.from(element.avatar);
let postPhotoBase64Str = postPhotoBuf.toString('base64')
commentList.pushData(new FriendMoment(element.id.toString(), element.nickName, avatarBase64Str, element.text,
postPhotoBase64Str));
}
});
return commentList;
}
页面完整代码如下,断点查看能从云数据库加载并返回commentList的最新数据,就是没有响应刷新UI。
import {HMRouter, HMRouterMgr} from "@hadss/hmrouter"
import DBUtil from '../util/DBUtil'
import {UserPost} from '../viewmodel/UserPost'
import { buffer } from '@kit.ArkTS';
import { promptAction, ToolBar, ToolBarOptions, ItemState } from '@kit.ArkUI';
import { FriendMoment, CommentData } from '../viewmodel/BasicDataSource';
import { OneMoment } from '../Components/OneMoment';
import Constants from '../common/Constants';
import { mockData, LoadUserPostData } from '../viewmodel/mockdata';
import { CommentInputDialog } from '../Components/CommentInputDialog';
const typeVideo: string = 'video';
const typeText: string = 'text';
const typeImage: string = 'image';
/**
* 功能描述: 本示例主要介绍使用@ohos.file.photoAccessHelper实现访问系统相册获取媒体资源的多媒体发布场景
*
* 推荐场景: 需要调用系统图库的场景,如:上传图库图片、发布朋友圈等
*
* 核心组件:
* 1. CommentInputDialog
*
* 实现步骤:
* 1.使用LazyForEach+cacheCount+@Reusable实现懒加载列表。
* 2.创建ListScroller对象,将ListScroller对象绑定到List组件内。
* 3.在需要记录当前位置时通过currentOffset方法存储当前偏移量historyOffset,在需要跳转时用scrollTo方法跳转。
*/
@HMRouter({
pageUrl: 'SharePosts',
})
@Entry
@Component
export struct SharePosts {
@StorageLink('hasLogin') hasLogin: boolean = false
@StorageLink('uid') uid: string = ''
@State result?: UserPost[] = []
@State imageBase64:string = ''
private cachedCountNumber: number = 3; // 懒加载缓存数
private controller1: TabsController = new TabsController()
listScroller: ListScroller = new ListScroller(); // scroller控制器
commentList: CommentData = new CommentData(); // 评论列表
@State textInComment: string = ""; // 评论中的文字
@State imageInComment: string = ''; // 评论中的图片列表
@State videoInComment: string = '' // 评论中的视频列表
@State dialogType: string = typeText; // 弹窗类型
private scroller: ListScroller = new ListScroller();
// 评论输入弹窗
dialogController: CustomDialogController | null = new CustomDialogController({
builder: CommentInputDialog({
textInComment: $textInComment,
imagesInComment: $imageInComment,
videoInComment: $videoInComment,
dialogType: $dialogType,
publish: () => this.publishComment()
}),
autoCancel: true,
alignment: DialogAlignment.Bottom,
customStyle: true,
offset: {
dx: $r('app.integer.image_comment_dialog_offset_x'),
dy: $r('app.integer.image_comment_dialog_offset_y')
}
});
async aboutToAppear(){
// // 加载初始数据
//this.commentList = mockData();
// 加载初始数据
this.commentList = await LoadUserPostData();
}
getCurrentDate(): string {
const date: Date = new Date();
return `${date.getFullYear()}-${date.getMonth()}-${date.getDay()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
}
publishComment(): void {
// 发布图片,须有选择图片
if (this.dialogType == typeImage) {
if (this.imageInComment !== undefined && this.imageInComment !== '') {
const comment: FriendMoment =
new FriendMoment(this.getCurrentDate(), "我的", $r("app.media.publish_multimedia_updates_photo0"),
this.textInComment, this.imageInComment);
this.commentList.addDataFirst(comment);
} else {
promptAction.showToast({
message: $r('app.string.publish_multimedia_updates_input_image'),
});
}
} else if (this.dialogType == typeVideo) {
// 发布视频,须有视频
if (this.videoInComment !== undefined && this.videoInComment !== '') {
const comment: FriendMoment =
new FriendMoment(this.getCurrentDate(), "我的", $r("app.media.publish_multimedia_updates_photo0"),
this.textInComment, '', this.videoInComment);
this.commentList.addDataFirst(comment);
} else {
promptAction.showToast({
message: $r('app.string.publish_multimedia_updates_input_video'),
});
}
} else if (this.dialogType == typeText) {
if (this.textInComment) {
const comment: FriendMoment =
new FriendMoment(this.getCurrentDate(), "我的", $r("app.media.publish_multimedia_updates_photo0"),
this.textInComment);
this.commentList.addDataFirst(comment);
} else {
promptAction.showToast({
message: $r('app.string.publish_multimedia_updates_input_comment'),
});
}
}
this.scroller.scrollToIndex(0, true, ScrollAlign.START);
}
aboutToDisappear() {
// 将dialogController置空
this.dialogController = null;
}
@Builder
MyMenu() {
Menu() {
MenuItem({
startIcon: $r("sys.media.ohos_ic_public_text"),
content: $r('app.string.publish_multimedia_updates_post')
})
.onClick(() => {
this.dialogType = typeText
if (this.dialogController !== null) {
// 打开评论输入弹窗
this.dialogController.open();
}
})
.id('Post')
MenuItem({
startIcon: $r("sys.media.save_button_picture"),
content: $r('app.string.publish_multimedia_updates_photo')
})
.onClick(() => {
this.dialogType = typeImage
if (this.dialogController !== null) {
// 打开评论输入弹窗
this.dialogController.open();
}
})
.id('Photo')
MenuItem({
startIcon: $r("sys.media.ohos_ic_public_video"),
content: $r('app.string.publish_multimedia_updates_video')
})
.onClick(() => {
this.dialogType = typeVideo
if (this.dialogController !== null) {
// 打开评论输入弹窗
this.dialogController.open();
}
})
.id('Video')
MenuItem({
startIcon: $r("app.media.camera"),
content: $r('app.string.publish_multimedia_updates_review')
})
.onClick(() => {
promptAction.showToast({
message: $r('app.string.publish_multimedia_updates_other_function'),
});
})
MenuItem({
startIcon: $r("sys.media.ohos_ic_public_camera"),
content: $r('app.string.publish_multimedia_updates_live')
})
.onClick(() => {
promptAction.showToast({
message: $r('app.string.publish_multimedia_updates_other_function'),
});
})
}
.width($r('app.string.publish_multimedia_updates_layout_40'))
}
@Builder
MyADD() {
Image($r('sys.media.ohos_ic_public_add'))
.bindMenu(this.MyMenu())
.width($r('app.string.publish_multimedia_updates_layout_40'))
.height($r('app.string.publish_multimedia_updates_layout_40'))
.position({ top: 20, right: 5 })
.id('add_button')
}
@Builder
Camera() {
Image($r('sys.media.ohos_ic_public_camera'))
.width($r('app.string.publish_multimedia_updates_layout_30'))
.position({ top: 15, left: 10 })
}
build() {
Row() {
Tabs({ controller: this.controller1, index: 1 }) {
TabContent() {
}.tabBar(this.Camera())
TabContent() {
Column() {
List({ space: Constants.LIST_SPACE, scroller: this.listScroller }) {
// TODO:高性能知识点:列表数据较多,不需要全部渲染上屏,采用LazyForEach。
LazyForEach(this.commentList, (moment: FriendMoment) => {
ListItem() {
OneMoment({ moment: moment });
}
}, (moment: FriendMoment) => moment.id)
}
// TODO:高性能知识点:为保证滑动流畅,采用cachedCount缓存前后节点。
.cachedCount(this.cachedCountNumber)
.width($r('app.string.publish_multimedia_updates_layout_100'))
.layoutWeight(1)
.listDirection(Axis.Vertical)
.divider({
strokeWidth: $r('app.integer.publish_multimedia_updates_divider_width'),
color: $r('app.color.publish_multimedia_updates_divider_color'),
startMargin: $r('app.integer.publish_multimedia_updates_list_divider_margin'),
endMargin: $r('app.integer.publish_multimedia_updates_list_divider_margin')
})
}
.height($r('app.string.publish_multimedia_updates_layout_100'))
.width($r('app.string.publish_multimedia_updates_layout_100'))
}.tabBar($r('app.string.publish_multimedia_updates_following'))
.height($r('app.string.publish_multimedia_updates_layout_100'))
.width($r('app.string.publish_multimedia_updates_layout_100'))
TabContent() {
Column()
.width($r('app.string.publish_multimedia_updates_layout_100'))
.height($r('app.string.publish_multimedia_updates_layout_100'))
.backgroundColor(Color.Blue)
}.tabBar($r('app.string.publish_multimedia_updates_for_you'))
TabContent() {
}.tabBar(this.MyADD())
}
.onContentWillChange((currentIndex, comingIndex) => {
if (comingIndex == 0 || comingIndex == 2 || comingIndex == 3) {
promptAction.showToast({
message: $r('app.string.publish_multimedia_updates_other_function'),
});
return false
}
if (comingIndex == 0) {
return false
}
return true
})
.vertical(false)
.barMode(BarMode.Fixed)
.height($r('app.string.publish_multimedia_updates_layout_100'))
.width($r('app.string.publish_multimedia_updates_layout_100'))
.barWidth($r('app.integer.publish_multimedia_updates_list_barwidth'))
.barHeight($r('app.integer.publish_multimedia_updates_list_barheight'))
}
.alignItems(VerticalAlign.Center)
.height($r('app.string.publish_multimedia_updates_layout_100'))
.width($r('app.string.publish_multimedia_updates_layout_100'))
}
}
更多关于HarmonyOS鸿蒙Next中请问一下各位大佬@ObservedV2 + @Trace在V1页面上混合使用时,为什么UI没有自动刷新页面又没报错?的实战教程也可以访问 https://www.itying.com/category-93-b0.html
3 回复
V1、V2混用时,有的错误能正常提示,有的可能不会提示,有的只是效果不正常,但是不影响程序运行。
个人建议分开使用,且以后估计会对V2新增更多功能,V1会慢慢淘汰掉。
更多关于HarmonyOS鸿蒙Next中请问一下各位大佬@ObservedV2 + @Trace在V1页面上混合使用时,为什么UI没有自动刷新页面又没报错?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
感谢回答,如果上面问题没解决,可能试试整个页面迁移到V2。
在HarmonyOS鸿蒙Next中,@ObservedV2
和@Trace
混合使用时,UI未自动刷新且无报错,可能是由于以下原因:
- 状态管理不一致:
@ObservedV2
和@Trace
可能未正确同步状态,导致UI未感知到数据变化。 - 生命周期问题:页面生命周期未正确触发状态更新,建议检查
onPageShow
或onPageHide
等生命周期方法。 - 依赖关系未建立:
@Trace
可能未正确绑定到@ObservedV2
的状态,导致依赖关系未建立,UI无法自动刷新。
建议检查状态管理和依赖关系,确保数据变化能正确触发UI更新。