Angular项目JS转TS后BMI组件无报错但无法运行问题求助
解决Angular项目中BMI组件无法运行的问题
我看了你的代码,发现核心问题是你把AngularJS(1.x)的代码逻辑直接硬塞进了Angular(2+)的TypeScript组件里——这俩是完全不同的框架,语法和运行机制不兼容,难怪项目在包含这个组件时跑不起来。我帮你把代码改成符合Angular规范的写法,同时保留原来的卡路里计算器功能:
修正后的 bmi.component.ts
import { Component, OnInit } from '@angular/core'; // 定义类型接口,避免滥用any interface Activity { name: string; multiply: number; } interface Goal { name: string; alt: string; cals: number; } interface MealNutrient { name: string; value: () => number; } @Component({ selector: 'app-bmi', templateUrl: './bmi.component.html', styleUrls: ['./bmi.component.css'] }) export class BmiComponent implements OnInit { // 替代原$scope的组件属性 activities: Activity[] = [ {name: 'Little to no exercise', multiply: 1.2}, {name: 'Light exercise (1–3 days per week)', multiply: 1.375}, {name: 'Moderate exercise (3–5 days per week)', multiply: 1.55}, {name: 'Heavy exercise (6–7 days per week)', multiply: 1.725}, {name: 'Very heavy exercise (twice per day, extra heavy workouts)', multiply: 1.9} ]; goals: Goal[] = [ {name: 'Lose weight - 1lb per week', alt: 'tone', cals: 500}, {name: 'Lose weight - 2lb per week', alt: 'tone', cals: 1000}, {name: 'Gain weight - 1lb per week', alt: 'bulk', cals: -500}, {name: 'Gain weight - 2lb per week', alt: 'bulk',cals: -1000}, {name: 'Maintain weight', alt: 'tone', cals: 0} ]; // 用户输入的参数 gender: 'male' | 'female' | undefined; weight: string = ''; height: string = ''; age: string = ''; selectedActivity: Activity | undefined; selectedGoal: Goal | undefined; constructor() { } ngOnInit(): void { } // 计算BMR的方法 bmr(): number | undefined { const weightNum = parseInt(this.weight, 10); const heightNum = parseInt(this.height, 10); const ageNum = parseInt(this.age, 10); // 先检查输入是否有效 if (isNaN(weightNum) || isNaN(heightNum) || isNaN(ageNum) || !this.gender) { return undefined; } const standard = weightNum * 10 + heightNum * 6.25 - ageNum * 5; if (this.gender === 'male') { return standard + 5; } else { return standard - 161; } } // 计算每日卡路里 cals(): number | undefined { const bmrValue = this.bmr(); if (bmrValue && this.selectedActivity && this.selectedGoal) { return bmrValue * this.selectedActivity.multiply - this.selectedGoal.cals; } return undefined; } // 蛋白质卡路里 proteinCals(): number | undefined { const totalCals = this.cals(); return totalCals ? totalCals * 0.55 : undefined; } // 碳水卡路里 carbsCals(): number | undefined { const totalCals = this.cals(); return totalCals ? totalCals * 0.25 : undefined; } // 脂肪卡路里 fatCals(): number | undefined { const totalCals = this.cals(); return totalCals ? totalCals * 0.2 : undefined; } // 各餐营养分配 get breakfast(): MealNutrient[] { return [ {name: 'protein', value: () => this.proteinCals() ? (this.proteinCals()! * 0.0252) / 4 : 0}, {name: 'carbs', value: () => this.carbsCals() ? (this.carbsCals()! * 0.0933) / 4 : 0}, {name: 'fat', value: () => this.fatCals() ? (this.fatCals()! * 0.3467) / 8 : 0} ]; } get snack(): MealNutrient[] { return [ {name: 'protein', value: () => this.proteinCals() ? (this.proteinCals()! * 0.0573) / 4 : 0}, {name: 'carbs', value: () => this.carbsCals() ? (this.carbsCals()! * 0.1295) / 4 : 0}, {name: 'fat', value: () => this.fatCals() ? (this.fatCals()! * 0.04) / 8 : 0} ]; } get mainMeal(): MealNutrient[] { return [ {name: 'protein', value: () => this.proteinCals() ? (this.proteinCals()! * 0.4014) / 4 : 0}, {name: 'carbs', value: () => this.carbsCals() ? (this.carbsCals()! * 0.2591) / 4 : 0}, {name: 'fat', value: () => this.fatCals() ? (this.fatCals()! * 0.2666) / 8 : 0} ]; } }
配套的 bmi.component.html 示例
<div class="calculator-container"> <!-- 用户输入区域 --> <div class="input-section"> <div> <label>Gender:</label> <select [(ngModel)]="gender"> <option value="male">Male</option> <option value="female">Female</option> </select> </div> <div> <label>Weight (lbs):</label> <input type="number" [(ngModel)]="weight" placeholder="Enter weight"> </div> <div> <label>Height (inches):</label> <input type="number" [(ngModel)]="height" placeholder="Enter height"> </div> <div> <label>Age:</label> <input type="number" [(ngModel)]="age" placeholder="Enter age"> </div> <div> <label>Activity Level:</label> <select [(ngModel)]="selectedActivity"> <option *ngFor="let activity of activities" [ngValue]="activity">{{activity.name}}</option> </select> </div> <div> <label>Goal:</label> <select [(ngModel)]="selectedGoal"> <option *ngFor="let goal of goals" [ngValue]="goal">{{goal.name}}</option> </select> </div> </div> <!-- 结果展示区域 --> <div class="results-section" *ngIf="cals()"> <h3>Your Daily Calorie Target: {{cals() | number}}</h3> <div class="nutrient-breakdown"> <p>Protein: {{proteinCals() | number}} cals</p> <p>Carbs: {{carbsCals() | number}} cals</p> <p>Fat: {{fatCals() | number}} cals</p> </div> <h4>Meal Breakdown</h4> <div class="meal-section"> <h5>Breakfast</h5> <p *ngFor="let item of breakfast">{{item.name}}: {{item.value() | number}}g</p> </div> <div class="meal-section"> <h5>Snack</h5> <p *ngFor="let item of snack">{{item.name}}: {{item.value() | number}}g</p> </div> <div class="meal-section"> <h5>Main Meal</h5> <p *ngFor="let item of mainMeal">{{item.name}}: {{item.value() | number}}g</p> </div> </div> </div>
关键修改说明
- 移除AngularJS遗留代码:删掉了
BmiComponent.module和app.controller这些AngularJS专属语法,Angular(2+)完全基于组件类来管理逻辑和状态。 - 添加TypeScript类型定义:创建了
Activity、Goal等接口,给组件属性和方法指定明确类型,避免any类型带来的潜在问题。 - 替换$scope为组件属性:原来绑定在$scope上的变量和方法,全部改成组件类的成员,Angular通过双向绑定(
[(ngModel)])和模板插值来访问这些属性。 - 修正类型检查逻辑:把错误的
Number(...) !== NaN改成!isNaN(),因为NaN和任何值比较结果都是false,无法正确判断是否为有效数字。 - 优化计算方法:给所有计算方法添加了空值检查,避免出现undefined导致的模板渲染错误。
内容的提问来源于stack exchange,提问作者karthik eyan
相关产品推荐
相关产品推荐

