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

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

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

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();
  }
}

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

相关推荐
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
爱敲代码的小鱼9 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
铅笔侠_小龙虾11 小时前
Flutter 实战: 计算器
开发语言·javascript·flutter
大模型玩家七七12 小时前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
2501_9447114312 小时前
JS 对象遍历全解析
开发语言·前端·javascript
发现一只大呆瓜13 小时前
虚拟列表:支持“向上加载”的历史消息(Vue 3 & React 双版本)
前端·javascript·面试
阔皮大师13 小时前
INote轻量文本编辑器
java·javascript·python·c#
lbb 小魔仙13 小时前
【HarmonyOS实战】React Native 表单实战:自定义 useReactHookForm 高性能验证
javascript·react native·react.js
_codemonster13 小时前
Vue的三种使用方式对比
前端·javascript·vue.js
全栈前端老曹14 小时前
【MongoDB】Node.js 集成 —— Mongoose ORM、Schema 设计、Model 操作
前端·javascript·数据库·mongodb·node.js·nosql·全栈