用户界面创建一个新的运动类型

● 现在我们需要根据我们之前规划的架构步骤来实现在用户界面创建一个运动类型

● 首先我们在要获取用户在表单中输入的数据

javascript 复制代码
 //从表单中获取数据
    const type = inputType.value;
    const distance = +inputDistance.value;
    const duration = +inputDuration.value;

● 然后针对与不同的运动类型来判断用户的输入是否正确

javascript 复制代码
//如果是跑步运动类型,创建跑步运动对象
    if (type === 'running') {
      const cadence = +inputCadence.value;
      if (
        !Number.isFinite(distance) || //输入的必须是属于否则报错
        !Number.isFinite(duration) ||
        !Number.isFinite(cadence)
      )
        return alert('输入的值必须是数字!');


    }

    //如果是骑行运动类型,创建骑行运动对象
    if (type === 'cycling') {
      const elevation = +inputElevation.value;
      if (
        !Number.isFinite(distance) ||
        !Number.isFinite(duration) ||
        !Number.isFinite(elevation)
      )
        return alert('输入的值必须是数字!');


    }

● 上面的写法明显违背了我们的不重复原则,所以我们更换一种写法

javascript 复制代码
//提交表单之后生成新的运动
  _newWorkout(e) {
//判断输入的值是否为数字,...inputs是一个剩余参数语法,把所有参数都放在一个数组里面
    const validInputs = (...inputs) =>
    //every方法,判断数组中的每个元素是否都满足条件,都满足返回true,否则返回false
      inputs.every(inp => Number.isFinite(inp));

    e.preventDefault(); //组织表单默认行为

    //从表单中获取数据
    const type = inputType.value;
    const distance = +inputDistance.value;
    const duration = +inputDuration.value;

    //如果是跑步运动类型,创建跑步运动对象
    if (type === 'running') {
      const cadence = +inputCadence.value;
      if (
        //判断输入的值是否为数字
        !validInputs(distance, duration, cadence)
      )
        return alert('输入的值必须是数字!');


    }

    //如果是骑行运动类型,创建骑行运动对象
    if (type === 'cycling') {
      const elevation = +inputElevation.value;
      if (!validInputs(distance, duration, elevation))
        return alert('输入的值必须是数字!');

    }

● 当然,这些数据并不是只要是数字就行了,还要不是负数,我们用相同的方法来书写

javascript 复制代码
_newWorkout(e) {
    //判断输入的值是否为数字,...inputs是一个剩余参数语法,把所有参数都放在一个数组里面
    const validInputs = (...inputs) =>
      //every方法,判断数组中的每个元素是否都满足条件,都满足返回true,否则返回false
      inputs.every(inp => Number.isFinite(inp));

    //判断输入的值是否为正数
    const allPositive = (...inputs) => inputs.every(inp => inp > 0);

    e.preventDefault(); //组织表单默认行为

    //从表单中获取数据
    const type = inputType.value;
    const distance = +inputDistance.value;
    const duration = +inputDuration.value;

    //如果是跑步运动类型,创建跑步运动对象
    if (type === 'running') {
      const cadence = +inputCadence.value;
      if (
        //判断输入的值是否为数字
        !validInputs(distance, duration, cadence) ||
        !allPositive(distance, duration, cadence)
      )
        return alert('输入的值必须是数字且必须为正数!');
    }

    //如果是骑行运动类型,创建骑行运动对象
    if (type === 'cycling') {
      const elevation = +inputElevation.value;
      if (
        !validInputs(distance, duration, elevation) ||
        !allPositive(distance, duration)
      )
        return alert('输入的值必须是数字且必须为正数!');
    }

● 现在我们就需要创建运动对象,并将数据存入进去

javascript 复制代码
 const type = inputType.value;
    const distance = +inputDistance.value;
    const duration = +inputDuration.value;
    const { lat, lng } = this.#mapEvent.latlng; //获取点击地图的经纬度
    let workout;

    //如果是跑步运动类型,创建跑步运动对象
    if (type === 'running') {
      const cadence = +inputCadence.value;
      if (
        //判断输入的值是否为数字
        !validInputs(distance, duration, cadence) ||
        !allPositive(distance, duration, cadence)
      )
        return alert('输入的值必须是数字且必须为正数!');
      workout = new Running([lat, lng], distance, duration, cadence); //创建跑步运动对象
    }

    //如果是骑行运动类型,创建骑行运动对象
    if (type === 'cycling') {
      const elevation = +inputElevation.value;
      if (
        !validInputs(distance, duration, elevation) ||
        !allPositive(distance, duration)
      )
        return alert('输入的值必须是数字且必须为正数!');
      workout = new Cycling([lat, lng], distance, duration, elevation); //创建骑行运动对象
    }

    //创建新的对象到workout数组中
    this.#workouts.push(workout);

数据已经正常可以拿到了;

● 然后通过修改type,来改变CSS样式

javascript 复制代码
class Running extends Workout {
  //继承Workout类
  type = 'running';
  constructor(coords, distance, duration, cadence) {
    super(coords, distance, duration); //调用父类构造函数
    this.cadence = cadence;
    this.calcPace();
  }
  //计算配速
  calcPace() {
    this.pace = this.duration / this.distance;
    return this.pace;
  }
}

class Cycling extends Workout {
  type = 'cycling';
  constructor(coords, distance, duration, elevationGain) {
    super(coords, distance, duration);
    this.elevationGain = elevationGain;
    this.calcSpeed();
  }
  //计算速度
  calcSpeed() {
    this.speed = this.distance / (this.duration / 60);
    return this.speed;
  }
}

 renderWorkoutMarker(workout) {
    L.marker(workout.coords)
      .addTo(this.#map)
      .bindPopup(
        L.popup({
          maxWidth: 250,
          minWidth: 100,
          autoClose: false,
          closeOnClick: false,
          className: `${workout.type}-popup`,
        })
      )
      .setPopupContent('运动')
      .openPopup();
  }
}

● 下篇文章将在地图上展现项目,并且消除一些关闭表单的一些小问题

相关推荐
海兰6 小时前
【应用】基于 Next.js 16 + Python mplfinance的金融K线图与技术指标可视化平台(三)
javascript·python·金融
小磊哥er7 小时前
深入解构Claude Code - 第 7 篇 · 连接外面的世界
javascript·ai编程
小磊哥er8 小时前
深入解构Claude Code - 第 6 篇 · 终端里的图形界面
javascript·ai编程
海兰8 小时前
【应用】基于 Next.js 16 + Python mplfinance的金融K线图与技术指标可视化平台(一)
javascript·python·金融
可乐鸡翅yeah_9 小时前
hls.js 内存泄漏实战排查,直播 M3U8 长时间播放异常定位方案
开发语言·javascript·python·django·ecmascript·m3u8·m3u8在线
可乐鸡翅yeah_9 小时前
第三方接口对接 M3U8 流媒体排坑实战,解决外部服务商流兼容难题
前端·javascript·python·django·html·m3u8·m3u8在线
默_笙10 小时前
🏠 「LLM Notes」:我用 Next.js + Redis 给自己造了个笔记博客
前端·javascript
ruanCat11 小时前
Prettier 明明执行成功,Markdown 为什么还是没变?一次插件误诊复盘
前端·javascript·node.js
软件开发技术深度爱好者12 小时前
在线学习实践 TypeScript 的官方Playground(演练场)使用介绍
javascript·学习·typescript
小磊哥er14 小时前
深入解构Claude Code - 第 5 篇 · 每次提问都给 AI 塞了什么资料
javascript·ai编程