数据模型——记录项

数据模型——记录项

由于我们之前在饮食记录列表等页面中定义的都是死数据,所以只能用一个数据模拟。为了丰富数据,贴近现实,我们这次课实现通过建立数据模型,为记录项填充更加丰富真实的数据。

在这里插入图片描述

通过效果图不难发现我们要实现的数据模型有两种类型,一种是记录项的类型,另外一种是饮食记录中的记录项类型,可以是食物或是运动。其包含的属性如上图所示。

数据模型两种类型

/**
 * 记录项类型
 */
export default class ItemCategory{
  /**
   * 类型id
   */
  id: number
  /**
   * 类型名称
   */
  name: ResourceStr

  constructor(id: number, name: ResourceStr) {
    this.id = id
    this.name = name
  }
}
/**
 * 饮食记录中的记录项,可以是食物或运动
 */
export default class RecordItem{
  /**
   * id
   */
  id: number
  /**
   * 名称
   */
  name: ResourceStr
  /**
   * 图片
   */
  image: ResourceStr
  /**
   * 分类id
   */
  categoryId: number
  /**
   * 包含的卡路里
   */
  calorie: number
  /**
   * 单位
   */
  unit: ResourceStr
  /**
   * 碳水含量,单位(克)
   */
  carbon: number
  /**
   * 蛋白质含量,单位(克)
   */
  protein: number
  /**
   * 脂肪含量,单位(克)
   */
  fat: number

  constructor(id: number, name: ResourceStr, image: ResourceStr,
              categoryId: number, unit: ResourceStr, calorie: number,
              carbon: number = 0, protein: number = 0, fat: number = 0) {
    this.id = id
    this.name = name
    this.image = image
    this.categoryId = categoryId
    this.unit = unit
    this.calorie = calorie
    this.protein = protein
    this.fat = fat
    this.carbon = carbon
  }
}

两种数据模型

记录项类型数据模型

import ItemCategory from '../viewmodel/ItemCategory'

/**
 * 食物类型的枚举
 */
enum FoodCategoryEnum{
  /**
   * 主食
   */
  STAPLE,
  /**
   * 蔬果
   */
  FRUIT,
  /**
   * 肉蛋奶
   */
  MEAT,
  /**
   * 坚果
   */
  NUT,
  /**
   * 其它
   */
  OTHER,
}

/**
 * 食物类型数组
 */
let FoodCategories = [
  new ItemCategory(0, $r('app.string.staple')),
  new ItemCategory(1, $r('app.string.fruit')),
  new ItemCategory(2, $r('app.string.meat')),
  new ItemCategory(3, $r('app.string.nut')),
  new ItemCategory(4, $r('app.string.other_type')),
]

/**
 * 运动类型枚举
 */
enum WorkoutCategoryEnum {
  /**
   * 走路
   */
  WALKING,
  /**
   * 跑步
   */
  RUNNING,
  /**
   * 骑行
   */
  RIDING,
  /**
   * 跳操
   */
  AEROBICS,
  /**
   * 游泳
   */
  SWIMMING,
  /**
   * 打球
   */
  BALLGAME,
  /**
   * 力量训练
   */
  STRENGTH
}

/**
 * 运动类型数组
 */
let WorkoutCategories = [
  new ItemCategory(0, $r('app.string.walking_type')),
  new ItemCategory(1, $r('app.string.running')),
  new ItemCategory(2, $r('app.string.riding')),
  new ItemCategory(3, $r('app.string.aerobics')),
  new ItemCategory(4, $r('app.string.swimming')),
  new ItemCategory(5, $r('app.string.ballgame')),
  new ItemCategory(6, $r('app.string.strength')),
]

export {FoodCategories , WorkoutCategories , FoodCategoryEnum, WorkoutCategoryEnum}

在这里我们除了建立记录项类型数据模型,还分别建立了两种类型的类型枚举,这在记录项数据模型和之后对记录项数据的应用中,发挥了重要的作用,有助于每一项数据项能方便的找到其所在的类型。

记录项数据模型

import RecordItem from '../viewmodel/RecordItem'
import ItemCategory from '../viewmodel/ItemCategory'
import { FoodCategories, FoodCategoryEnum, WorkoutCategories, WorkoutCategoryEnum } from './ItemCategoryModel'
import GroupInfo from '../viewmodel/GroupInfo'


const foods: RecordItem[] = [
  new RecordItem(0, '米饭',$r('app.media.rice'),FoodCategoryEnum.STAPLE, '碗',  209, 46.6, 4.7, 0.5),
  new RecordItem(1, '馒头',$r('app.media.steamed_bun'),FoodCategoryEnum.STAPLE, '个',  114, 24.0, 3.6, 0.6),
  new RecordItem(2, '面包',$r('app.media.bun'),FoodCategoryEnum.STAPLE, '个',  188, 35.2, 5.0, 3.1),
  new RecordItem(3, '全麦吐司',$r('app.media.toast'),FoodCategoryEnum.STAPLE, '片',  91, 15.5, 4.4, 1.3),
  new RecordItem(4, '紫薯',$r('app.media.purple_potato'),FoodCategoryEnum.STAPLE, '个',  163, 42.0, 1.6, 0.4),
  new RecordItem(5, '煮玉米',$r('app.media.corn'),FoodCategoryEnum.STAPLE, '根',  111, 22.6, 4.0, 1.2),
  new RecordItem(6, '黄瓜',$r('app.media.cucumber'),FoodCategoryEnum.FRUIT, '根',  29, 5.3, 1.5, 0.4),
  new RecordItem(7, '蓝莓',$r('app.media.blueberry'),FoodCategoryEnum.FRUIT, '盒',  71, 18.1, 0.9, 0.4),
  new RecordItem(8, '草莓',$r('app.media.strawberry'),FoodCategoryEnum.FRUIT, '颗',  14, 3.1, 0.4, 0.1),
  new RecordItem(9, '火龙果',$r('app.media.pitaya'),FoodCategoryEnum.FRUIT, '个',  100, 24.6, 2.2, 0.5),
  new RecordItem(10, '奇异果',$r('app.media.kiwi'),FoodCategoryEnum.FRUIT, '个',  25, 8.4, 0.5, 0.3),
  new RecordItem(11, '煮鸡蛋',$r('app.media.egg'),FoodCategoryEnum.MEAT, '个',  74, 0.1, 6.2, 5.4),
  new RecordItem(12, '煮鸡胸肉',$r('app.media.chicken_breast'),FoodCategoryEnum.MEAT, '克',  1.15, 0.011, 0.236, 0.018),
  new RecordItem(13, '煮鸡腿肉',$r('app.media.chicken_leg'),FoodCategoryEnum.MEAT, '克',  1.87, 0.0, 0.243, 0.092),
  new RecordItem(14, '牛肉',$r('app.media.beef'),FoodCategoryEnum.MEAT, '克',  1.22, 0.0, 0.23, 0.033),
  new RecordItem(15, '鱼肉',$r("app.media.fish"),FoodCategoryEnum.MEAT, '克',  1.04, 0.0, 0.206, 0.024),
  new RecordItem(16, '牛奶',$r("app.media.milk"),FoodCategoryEnum.MEAT, '毫升',  0.66, 0.05, 0.03, 0.038),
  new RecordItem(17, '酸奶',$r("app.media.yogurt"),FoodCategoryEnum.MEAT, '毫升',  0.7, 0.10, 0.032, 0.019),
  new RecordItem(18, '核桃',$r("app.media.walnut"),FoodCategoryEnum.NUT, '颗',  42, 1.2, 1.0, 3.8),
  new RecordItem(19, '花生',$r("app.media.peanut"),FoodCategoryEnum.NUT, '克',  3.13, 0.13, 0.12, 0.254),
  new RecordItem(20, '腰果',$r("app.media.cashew"),FoodCategoryEnum.NUT, '克',  5.59, 0.416, 0.173, 0.367),
  new RecordItem(21, '无糖拿铁',$r("app.media.coffee"),FoodCategoryEnum.OTHER, '毫升',  0.43, 0.044, 0.028, 0.016),
  new RecordItem(22, '豆浆',$r("app.media.soybean_milk"),FoodCategoryEnum.OTHER, '毫升',  0.31, 0.012, 0.030, 0.016),
]

const workouts: RecordItem[] = [
  new RecordItem(10000, '散步',$r('app.media.ic_walk'), WorkoutCategoryEnum.WALKING, '小时', 111),
  new RecordItem(10001, '快走',$r('app.media.ic_walk'), WorkoutCategoryEnum.WALKING, '小时',  343),
  new RecordItem(10002, '慢跑',$r('app.media.ic_running'), WorkoutCategoryEnum.RUNNING, '小时',  472),
  new RecordItem(10003, '快跑',$r('app.media.ic_running'), WorkoutCategoryEnum.RUNNING, '小时',  652),
  new RecordItem(10004, '自行车',$r('app.media.ic_ridding'), WorkoutCategoryEnum.RIDING, '小时',  497),
  new RecordItem(10005, '动感单车',$r('app.media.ic_ridding'), WorkoutCategoryEnum.RIDING, '小时',  587),
  new RecordItem(10006, '瑜伽',$r('app.media.ic_aerobics'), WorkoutCategoryEnum.AEROBICS, '小时',  172),
  new RecordItem(10007, '健身操',$r('app.media.ic_aerobics'), WorkoutCategoryEnum.AEROBICS, '小时',  429),
  new RecordItem(10008, '游泳',$r('app.media.ic_swimming'), WorkoutCategoryEnum.SWIMMING, '小时',  472),
  new RecordItem(10009, '冲浪',$r('app.media.ic_swimming'), WorkoutCategoryEnum.SWIMMING, '小时',  429),
  new RecordItem(10010, '篮球',$r('app.media.ic_basketball'), WorkoutCategoryEnum.BALLGAME, '小时',  472),
  new RecordItem(10011, '足球',$r('app.media.ic_football'), WorkoutCategoryEnum.BALLGAME, '小时',  515),
  new RecordItem(10012, '排球',$r("app.media.ic_volleyball"), WorkoutCategoryEnum.BALLGAME, '小时',  403),
  new RecordItem(10013, '羽毛球',$r("app.media.ic_badminton"), WorkoutCategoryEnum.BALLGAME, '小时',  386),
  new RecordItem(10014, '乒乓球',$r("app.media.ic_table_tennis"), WorkoutCategoryEnum.BALLGAME, '小时',  257),
  new RecordItem(10015, '哑铃飞鸟',$r("app.media.ic_dumbbell"), WorkoutCategoryEnum.STRENGTH, '小时',  343),
  new RecordItem(10016, '哑铃卧推',$r("app.media.ic_dumbbell"), WorkoutCategoryEnum.STRENGTH, '小时',  429),
  new RecordItem(10017, '仰卧起坐',$r("app.media.ic_sit_up"), WorkoutCategoryEnum.STRENGTH, '小时',  515),
]

class ItemModel{
  //查出全部(默认查食物)
   list(isFood:boolean=true):RecordItem[]{
     return isFood? foods:workouts
   }
//定义接口生成GroupInfo类型数组组合真正数据集合(按组查询)
  listItemGroupByCategory(isFood:boolean=true){
    //判断要处理的是食物还是运动
    let categories=isFood? FoodCategories:WorkoutCategories
    let items=isFood? foods:workouts
     //1.创建空分组
    let groups= categories.map(itemCategory => new GroupInfo(itemCategory,[]))
    //2.遍历记录项列表将食物添加到对应分组
    items.forEach(item => groups[item.categoryId].items.push(item))
    //3.返回结果
    return groups;
  }

}

let itemModel = new ItemModel()

export default itemModel as ItemModel

在其中我们要注意的是在ItemModel类中,我们封装了两个方法,实现了在判断是食物还是运动后,全部查询数据项,或按组别(类型)查询数据项。效果如下:

| 在这里插入图片描述
| 在这里插入图片描述
|
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| 在这里插入图片描述
| 在这里插入图片描述
|

实现全部查询

  1. 我们首先声明状态变量,确定点击的是三餐之一,还是运动,以便于动态显示数据。

    @State isFood:boolean=false;
    
  2. 然后再Tabs的tabBar为‘全部’的TabContent中使用TabContentBuilder,将TabContentBuilder的内容更换为通过ItemModel.list(this.isFood)查询到的全部数据。

    TabContent(){
    this.TabContentBuilder(ItemModel.list(this.isFood))
    }
    .tabBar('全部')
    
  3. 此时TabContentBuilder中的数据不再是死数据,也要进行一定的修改。

  @Builder TabContentBuilder(items:RecordItem[]){
    List({space:CommonConstants.SPACE_10}){
      ForEach(items,(item:RecordItem)=>{
        ListItem(){
          Row({space:CommonConstants.SPACE_6}){
            Image(item.image).width(50)
            Column({space:CommonConstants.SPACE_4}){
              Text(item.name).fontWeight(CommonConstants.FONT_WEIGHT_500)
              Text(`${item.calorie}千卡/${item.unit}`).fontSize(14).fontColor($r('app.color.light_gray'))
            }
            Blank();
            Image($r('app.media.ic_public_add_norm_filled'))
              .width(18)
              .fillColor($r('app.color.primary_color'))
          }
          .width('100%')
          .padding(CommonConstants.SPACE_6)
        }.onClick(()=>this.showPanel(item))           //点击时父页面的底部面板显示
      })
    }
    .width('100%')
    .height('100%')
  }

实现按类型查询

想要显示所有的类型作为tabBar,而且不同类型的TabContent中的记录项也要符合其类型。需要做如下操作:

  1. 定义组合类型,用来将类型和类型所包含的数据项组合起来
import ItemCategory from './ItemCategory'
import RecordItem from './RecordItem'
export default class GroupInfo{
  type:ItemCategory
  items:RecordItem[]

  constructor(type:ItemCategory,items:RecordItem[]) {
    this.type=type;
    this.items=items;
  }
}

2.接着,我们在数据项模型中,定义接口,在确定是运动还是食物后,能返回记录类型和其对应的记录项数组所组成的数据分组。

//定义接口生成GroupInfo类型数组组合真正数据集合(按组查询)
  listItemGroupByCategory(isFood:boolean=true){
    //判断要处理的是食物还是运动
    let categories=isFood? FoodCategories:WorkoutCategories
    let items=isFood? foods:workouts
     //1.创建空分组
    let groups= categories.map(itemCategory => new GroupInfo(itemCategory,[]))
    //2.遍历记录项列表将食物添加到对应分组
    items.forEach(item => groups[item.categoryId].items.push(item))
    //3.返回结果
    return groups;
  }

3.在Tabs通过遍历将所有类型及其对应数据项数组渲染

  ForEach(ItemModel.listItemGroupByCategory(this.isFood),(group:GroupInfo)=>{
        TabContent(){
          this.TabContentBuilder(group.items)
        }
        .tabBar(group.type.name)
      })

每个记录项的panel数据更新

1.通过onPanelShow接收所需要的item

onPanelShow(item:RecordItem){
  //初始化当前键盘值和绿色下划线上的文本值
  this.amount=1;
  this.value='';
  this.showPanel=true;
  this.item=item;
}

2.在Panel中将item传递给ItemCard

//3.底部面板
Panel(this.showPanel){
  //3.1.顶部日期
  ItemPanelHeader()

  //3.2.记录项卡片
  if (this.item){
    ItemCard({amount:this.amount,item:$item})

  }

3.在ItemCard使用item的数据代替死数据,实现如下效果:

在这里插入图片描述
在这里插入图片描述
  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值