Distance Calculation in Angular

断了今生、忘了曾经 提交于 2019-12-22 18:03:08

问题


I am making a distance calculation application using angular which has,

Html:

<form [formGroup]="form" *ngIf="showForm">
<div formArrayName="distance" >
<table>
  <thead>
      <th> From Distance (Km) </th>
      <th> To Distance (Km) </th>
      <th> Fare Per Kilometer </th>
    </thead>
    <tbody>
    <tr 
      *ngFor="let item of form.get('distance').controls; let i = index" 
      [formGroupName]="i">
      <td>
      <input type="number" 
        placeholder="From" 
        formControlName="from">
        </td>
      <td>
        <input type="number"
          placeholder="To" 
          formControlName="to">
      </td>
       <td>
        <input type="number"
          placeholder="Fare Per Km" 
          formControlName="farePerKm">
      </td>
     </tr>
    </tbody>
   </table>
  </div>
</form>

TS:

  selectedValues(e) {
    this.showForm = true;
    this.form = this.fb.group({
      distance: this.fb.array([]),
    });
    const control = this.form.controls.distance as FormArray;
    if (e.target.value === "V1") {
      this.vehicleOne.forEach(data => {
        control.push(this.fb.group({
          from: [data.from, Validators.required],
          to: [data.to, Validators.required],
          farePerKm: [data.farePerKm, Validators.required]
        }));
      });
    }
    else if (e.target.value === "V2") {
      this.vehicleTwo.forEach(data => {
        control.push(this.fb.group({
          from: [data.from, Validators.required],
          to: [data.to, Validators.required],
          farePerKm: [data.farePerKm, Validators.required]
        }));
      });
    }
  }

The above code is just for the reference, the entire code is here at the working example https://stackblitz.com/edit/disable-group-control-value-on-another-control-value-for-itrxah

Requirement: In this example you can see that there is a select dropdown initially shows choose a vehicle, upon choosing any one of the two vehicle you will get the fare per kilometer for the vehicle based on the from and to km basis in a table.

After this table there is a three dropdown says From Location, To Location, Total distance Travelled and an empty input box says total fare.

Thing i am in the need is if user selects Vehicle One(vehicle), Location A (From Location), Location C (To Location), 20KM (Total Distance travelled) then the total fare input needs to be updated with the value of 350.

Based on the above selection (where total distance travelled was 20Km in vehicle one) the calculation will be,

For the first 5 KMS (0 - 5), the fare is 10 / km so 5*10 = 50, where for next 15 KMS (6 to 20) the fare is 20 / km so 15*20 = 300.

So total fare was 50 + 300 = 350

The above given scenario is just for example and like this if i choose second vehicle then the fare needs to get calculated according to it km split up and fare/km.

If the selection was like the above said then total fare input value,

<input type="number"
          placeholder="Fare Per Km" 
          formControlName="farePerKm">

needs to be updated with the above calculated value of 350 as per the above given example which vary depends on selection.

Edit: Please don't bother about the given structure because in my real application i am using maps to calculate the distance travelled i have made it everything inside form now.

Only requirement is i need to get the total fare value of the total distance travelled by a rider in a vehicle which has fare calculation spit up based on km as like given.

The below given is vehicle one split up. So if i am travelling in this vehicle one for 20km then total fare needs to be 350 (For eg) likewise for any other vehicle different split up.

From Distance (Km)  To Distance (Km)    Fare Per Kilometer

0                    5                   10

6                    20                  20

回答1:


just make a function to calculate price.

Well, before, you must defined better the "fares", in the fares must be equal the to and the next from, that's

vehicleOne: any = [{ from: "0", to: "5", farePerKm: "10" }, 
                   { from: "5", to: "20", farePerKm: "20" }, //<--"from" is equal to "to" above
                   { from: "20", to: "50", farePerKm: "5" }] //<--"from" is equal to "to" above

else, what is the price of make "6Km" with vehicle "V1"?

The function is easy:

  getPrice(vehicleID: string, distance: number) {
    //get the fare
    let fare: any[];
    switch (vehicleID) {
      case "V1":
        fare = this.vehicleOne;
        break;
      case "V2":
        fare = this.vehicleTwo;
        break;
    }
    let price: number = 0;
    let distanceCal = distance;
    fare.forEach(x => {
      let incprice=0;
      if (distanceCal > 0) {
        if (distance > +x.to)
          incprice += ((+x.to) - (+x.from)) * (+x.farePerKm);
        else
          incprice += (distance-(+x.from)) * (+x.farePerKm);

        price+=incprice
        distanceCal -= (+x.to) - (+x.from)
      }
    })
    if (distanceCal>0) //If the distance if greater than the last fare
      price+=distanceCal * (+fare[fare.length-1].farePerKm) //use the last farePerKm

    return price;
  }

Well, using a switch to select the fare is some strange. You can improve the code if your fares goes as

vehicles: any = [
   { id: "V1", vehicleName: "Vehicle One", fares: [{ from: "0", to: "5", farePerKm: "10" }, { from: "5", to: "20", farePerKm: "20" }] },
   { id: "V2", vehicleName: "Vehicle Two", fares: [{ from: "0", to: "10", farePerKm: "15" }, { from: "10", to: "20", farePerKm: "12" }] }

And then you can change the function as

getPrice(vehicleID: string, distance: number) {
    //get the fare
    let fare= this.vehicles.find(x=>x.id==vehicleID).fares;
    ....rest of the code...
}

NOTE: as in your fares, from,to and farePerKm are strings, you must convert to number using "+" NOTE2: you must check the function. e.g. you can in a ngOnInit -only for check- write some like

for (let distance=0;distance<30;distance++)
      console.log(distance,this.getPrice("V1",distance))



回答2:


Here you go. I only put in the code I had to add or adjust in order to solve your problem. Please note that this is not a full solution but a hint to get you in the right direction.

In your AppModule add the FormsModule in order to be able to use the ngModule-directive.

import { ReactiveFormsModule, FormsModule } from '@angular/forms';

@NgModule({
imports:      [ BrowserModule, ReactiveFormsModule, FormsModule ],
...

In your TS-file add the following variables:

protected totalFare: string;
protected chosenVehicle: any;
protected selectedDistance: any;

Also extend your vehicles-list

vehicles: any = [
{ id: "V1", vehicleName: "Vehicle One", fares: [{ from: "0", to: "5", farePerKm: "10" }, { from: "6", to: "20", farePerKm: "20" }] },
{ id: "V2", vehicleName: "Vehicle Two", fares: [{ from: "0", to: "10", farePerKm: "15" }, { from: "11", to: "20", farePerKm: "12" }] }

]

And add the following method

protected onDistanceSelection(): void {
    const vehicle = this.vehicles.filter(el => el.id === this.chosenVehicle)[0];
    this.totalFare = vehicle.fares[0].farePerKm;
}

In your HTML-File do the following adjustments:

<select (change)="selectedValues($event)" [(ngModel)]="chosenVehicle">
  <option value="undefined" disabled selected> Choose a vehicle </option>
  <option *ngFor="let vehicle of vehicles" [value]="vehicle.id"> {{  vehicle.vehicleName  }} </option>
</select>



 <select (change)="onDistanceSelection()" [(ngModel)]="selectedDistance">
     <option value="undefined"  disabled selected> Total distance of travel</option>
     <option value="10"> 10 KM </option>
     <option value="20"> 20 KM </option>
     <option value="30"> 30 KM </option>
     <option value="40"> 20 KM </option>
</select>


<input type="text" [(ngModel)]="totalFare" placeholder="Total fare">

Please note that you wrote "undefined" wrong in most of your code. I corrected it here. Otherwise ther dropdowns will show no "Select..." text at start.

What you can see using this code is, that by chosing a vehicle and clicking the distance, the farePerKm of the current vehicle is shown in the total fare textfield.

Give this it should be possible for you to start computing on your own inside onDistanceSelection(). You also have access on selectedDistance here.

Have fun! ;)



来源:https://stackoverflow.com/questions/54427048/distance-calculation-in-angular

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!