HarmonyOS 鸿蒙Next中卡片绑定数据失败

HarmonyOS 鸿蒙Next中卡片绑定数据失败 本来使用关系型数据库查询数据绑定卡片,结果不显示数据,尝试使用死数据,结果也没有绑定到卡片上,请问是怎么回事

cke_1800.png

cke_3231.png

cke_3786.png

cke_5150.png


更多关于HarmonyOS 鸿蒙Next中卡片绑定数据失败的实战教程也可以访问 https://www.itying.com/category-93-b0.html

13 回复

可以参考文档:卡片内容更新

更多关于HarmonyOS 鸿蒙Next中卡片绑定数据失败的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


你好。请把Promise<number>这里换成string,初始值total也改成’0’,试试看喃。

还是不可以,查询数据的方法应该是没问题的,在普通的页面中是可以显示数据的 ,只是不可以将数据显示到卡片中,通过查看日志,在卡片的onAddForm生命周期中,我前面发的异步获取实际值并更新方法是没有执行的,可能还是异步的问题,不知道怎么修改,

你好。请再试试看呢,我感觉数据类型一直没统一,也有可能Promise触发的时机不对。

数据库查询

getTodayExpense(): Promise<number> {
  return new Promise((resolve, reject) => {
    const today = new Date().toISOString().split('T')[0];
    const sql = `SELECT SUM(accountInOutMoney) as total FROM AccountInOut WHERE accountInOutDate = ?`;
    RdbUtils.rdbStore.querySql(sql, [today], (err, resultSet) => {
      if (err) {
        console.error("数据库错误:", err);
        reject(err);
        return;
      }
      const total = resultSet?.goToNextRow() ? resultSet.getDouble(resultSet.getColumnIndex('total')) || 0 : 0;
      resultSet?.close();
      console.log("今日消费:", total); 
      resolve(total);
    });
  });
}

卡片更新逻辑

async onAddForm(want: Want) {
  try {
    const expense = await new rdbUtils().getTodayExpense();
    const formId = want.parameters?.[formInfo.FormParam.IDENTITY_KEY];
    if (!formId) throw new Error("无效 formId");
    
    await formProvider.updateForm(
      formId.toString(),
      formBindingData.createFormBindingData({ todayExpense: expense })
    );
    console.log("更新成功");
  } catch (err) {
    console.error("卡片更新失败:", err);
  }
}

卡片的onAddForm不可以使用async异步,会报错,前面也加了日志输出吗,在onAddForm中调用的getTodayExpense没有日志输出,在其他页面中是有的。

您好,为了更快速解决您的问题,并且吸引更多用户一同参与您问题的解答与讨论,建议您补全如下信息:

补全复现代码,让参与用户更快速复现您的问题;

更多提问技巧,请参考:【Tips】如何提个好问题

请问解决了吗?

我已经可以接受到默认设定的数据,但是在换成查询数据库的数据时,没有反应。查询数据库的是一个异步方法。

卡片数据查询

getTodayExpense(): Promise<number> {
  return new Promise((resolve, reject) => {
    const date = new Date()
    const today = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate()
    const sql = `SELECT SUM(accountInOutMoney) as total
               FROM AccountInOut
               WHERE accountInOutDate = '${today}'`;
    RdbUtils.rdbStore.querySql(sql, (err, resultSet) => {
      if (err) {
        reject(err);
        return;
      }
      let total = 0;
      if (resultSet.goToNextRow()) {
        total = resultSet.getDouble(resultSet.getColumnIndex('total')) || 0;
        console.log("dasdasda", total)
      }
      resultSet.close();
      resolve(total);
    });
  });
}

我采用了这种方式

onAddForm(want: Want) {
  const rdbUtil: rdbUtils = new rdbUtils();
  let todayExpenseDate: BindingData = {
    todayExpense: "暂无消费"
  }
  // 异步获取实际值并更新
  rdbUtil.getTodayExpense().then((expense: number) => {
    let bindDate = formBindingData.createFormBindingData(expense);
    let wantParams: Record<string, object> | undefined = want.parameters;
    if (wantParams) {
      let formId = wantParams[formInfo.FormParam.IDENTITY_KEY];
      formProvider.updateForm(formId.toString(), bindDate).then(res => {
        console.log("更新成功", res);
      })
    }
  }); 但是不会更新数据

然后我使用定时器模拟异步操作,是可以正常更新的

// 模拟异步操作
setTimeout(() => {
  let todayExpenseDate: BindingData = {
    todayExpense: "555"
  }
  let bindDate = formBindingData.createFormBindingData(todayExpenseDate);
  let wantParams: Record<string, object> | undefined = want.parameters;
  if (wantParams) {
    let formId = wantParams[formInfo.FormParam.IDENTITY_KEY];
    formProvider.updateForm(formId.toString(), bindDate).then(res => {
      console.log("更新成功", res);
    })
  } else {
    console.log("更新失败");
  }
}, 1000)

不知道问题出在哪,

卡片内容更新的方法updateForm在上面那个文档的正下方,可以参考下呢:

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V14/arkts-ui-widget-interaction-overview-V14

你好。根据代码截图来看,todayExpense数据是使用LocalStorage来保存的,但是在窗口EntryFormAbility中return的数据没有和LocalStorag产生关联,建议修改试试看:

export default class EntryFormAbility extends FormExtensionAbility {
    onAddForm(want: Want) {
        let store = new LocalStorage();
        store.setOrCreate("todayExpense", 555);
        return formBindingData.createFormBindingData(store);
    }
}

希望可以帮助到你。

按照您的方法修改后,卡片页面还是没有接受到,

你好。如果要实现动态刷新,可以参考下:

  1. 首先卡片和应用之间可以通过 postCardAction 来实现跳转交互和传参,在卡片的文件页面中进行修改:
Text("消费卡片")..onClick((event: ClickEvent) => {
  // 动态卡片跳转,通过 params 传参
  postCardAction(this,{
    action:'router',
    abilityName:'EntryFormAbility',
    params:{
      todayExpense:"555"
    }
  })
})
  1. 把窗口页面的启动页面设置为要跳转的页面
windowStage.loadContent('pages/要跳转的页面', (err) => {
});
  1. 在要跳转的目标窗口文件中,可以通过 onCreateonNewWant 两个生命周期函数来接收卡片跳转时传递的参数
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  console.log('onCreate 接收的参数', JSON.stringify(want?.parameters?.params))
}

onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  console.log('onNewWant 接收的参数', JSON.stringify(want?.parameters?.params))
}
  1. 在窗口的 onCreateonNewWant 生命周期中,接收参数,并更新卡片数据,调用卡片的 updateForm 方法,将卡片 ID 和最新的数据传递过去,实现卡片的刷新

  2. 在卡片的配置文件 /resources/base/profile/form_config.json 中配置自动刷新还是手动刷新,

这个是定时刷新的:

{
    "updateEnabled": true,
    "updateDuration": 2   // 2 表示 2x30分钟
}

这个是定点刷新的:

{
      "updateEnabled": true,
    "scheduledUpdateTime": "按你的需要配置具体时间",
    "updateDuration": 0
}
  1. 调用卡片的 updateForm 方法,将卡片 ID 和最新的数据传递过去,实现卡片的刷新
formProvider.updateForm(formId, formMsg).then((data) => {
  console.log("金额更新成功", data)
})

中间的代码太长了评论窗口较小发不出来,具体的代码和方法可以参考文档:

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V14/arkts-ui-widget-event-router-V14

希望可以帮助到你。

在HarmonyOS鸿蒙Next中,卡片绑定数据失败可能是由于以下几个原因导致的:

  1. 数据源问题:确保数据源正确且可用,检查数据源是否已初始化或是否存在网络问题。

  2. 卡片配置错误:检查卡片的配置文件(如config.json)是否正确,确保数据绑定的字段与数据源匹配。

  3. 生命周期管理:确认卡片和数据源的生命周期管理是否正确,避免在卡片未加载或已销毁时进行数据绑定。

  4. 权限问题:确保应用有足够的权限访问数据源,特别是涉及跨应用数据绑定时。

  5. 代码逻辑错误:检查数据绑定的代码逻辑,确保在正确的时机调用数据绑定方法。

建议逐一排查以上问题,确保数据绑定的每个环节都正确无误。

回到顶部