简体   繁体   中英

Default Select option Angular 8 Reactive forms

I want to get all my data from my API and set them as defaults for my reactive form. I was able to bind all the values using ngModel . I just don't know how I can do this with my select . In my HTML I am getting my 1st select option from my home service. The second option onward, I am using my category service to display all the categories. I did this so that I am able to have defaults according to the product I currently have selected. The main problem I am running into is that I want to bind the ngModel to the first option so that by default if I were to submit my form it would be the first option submitted. I have seen people use patch value to do this but my problem is I don't know how to do this with the data I am getting through my html because it's being displayed in the html not in the the ts file. Using ngModel is the best solution I could come with.

html

  <!-- Table -->
  <form  [formGroup]="updateProduct" >
      <p>
          Form Status: {{updateProduct.value |json}}
        </p>
  <div class="table-responsive">
     
    <table  class="table table-bordered table-striped">
      <thead>
      <tr>
        <th>Id</th>
        <th>Product</th>
        <th>Category</th>
        <th>FullPrice <i id ="asc-desc1"class="fas fa-angle-down" (click)="SortPrice($event)"></i></th>
        <th>Saleprice <i id ="asc-desc2"class="fas fa-angle-down" (click)="SortSale($event)"></i> </th>
        <th>Availablity</th>
        <th>Supplier</th>
        <th>Discount<i id ="asc-desc3"class="fas fa-angle-down" (click)="SortDiscount($event)"></i></th>
        <th>Edit</th>
      </tr>
      </thead>
      <tbody>
          
        <tr  *ngFor="let home of home | paginate:{itemsPerPage:20,currentPage: p} ; index as i">
        <ng-container *ngIf="editMode !== i">
        <td>{{home.id}}</td>
        <td>{{home.productName}}</td>
        <td>{{home.category.categoryName}}</td>
        <td>{{home.fullPrice}}</td>
        <td>{{home.salePrice}}</td>
        <td>{{home.availability}}</td>
        <td>{{home.supplier.supplierName}}</td>
        <td>{{home.discount }}</td>
      </ng-container>
      <ng-container *ngIf="editMode === i">
          
          <td><input class="form-control" id="id"  formControlName="id" [(ngModel)]="home.id" disabled></td>
          <td><input class="form-control" id="productName"  formControlName="productName" [(ngModel)]="home.productName"></td>
          <td>
              <select class="form-control" formControlName="category" >
                <option selected="selcected"  class="opt1" >{{home.category.categoryName}}</option>
                <option *ngFor="let category of categories">{{category.categoryName}}</option>
              </select>
            </td>
          <td><input class="form-control" id="fullprice" formControlName="fullPrice" [(ngModel)]="home.fullPrice"></td>
          <td><input class="form-control" id="saleprice"   formControlName="salePrice" [(ngModel)]="home.salePrice"></td>
          <td><input type="checkbox" class="form-control" id="availability"  formControlName="availability" [(ngModel)]="home.availability"></td>
          <td>
            <select class="form-control" formControlName="supplier">
              <option selected="selcected" class="opt1">{{home.supplier.supplierName}}</option>
              <option *ngFor="let supplier of suppliers">{{supplier.supplierName}}</option>
            </select>
          </td>
          <td><input class="form-control" id="discount" formControlName="discount"[(ngModel)]="home.discount"></td>
     
        </ng-container>


      <!-- if assigned index to editMode matches -->
      
        <td class="text-right" id="tableDataBtns">
          <div class="btn-group" role="group">
            <button (click)="editMode === i ? editMode = null : editMode = i" data-toggle="modal" data-target="#updateProduct" type="button" class="btn btn-secondary">
              <ng-container *ngIf="editMode === i"><i class="far fa-save"></i></ng-container>
              <ng-container *ngIf="editMode !== i"><i class="far fa-edit"></i></ng-container>
            </button>
            <button type="button" data-toggle="modal" data-target="#deleteProduct" class="btn btn-danger"><i class="far fa-trash-alt"></i></button>
          </div>
        </td>
      </tr>
      </tbody>
    </table>

    <pagination-controls class="myPagination" (pageChange)="p= $event"></pagination-controls>
  </div>
  </form>
ts

import { Component, OnInit } from '@angular/core';
import { Product } from '../model/Product';
import { Category } from '../model/Availability';
import { Supplier } from '../model/Supplier';
import { Home } from '../model/Home';
import { HomeService } from '../service/Home.service';
import { SupplierService } from '../service/Supplier.service';
import { CategoryService } from '../service/Category.service';
import { FormGroup, FormControl } from '@angular/forms'
@Component({
  selector: 'app-update-product',
  templateUrl: './update-product.component.html',
  styleUrls: ['./update-product.component.scss']
})
export class UpdateProductComponent implements OnInit {
  availability:boolean;
  category:number;
  orderBy: String;
  Ascdesc: String;
  page = 0;
  home: Home[];
  categories: Category[];
  suppliers: Supplier[];
  selectedCategory: Category;
  edit: boolean = false;
  public currentProduct: number;

  toogleEditMode() {
    this.edit = this.edit ? false : true; 
  }
    
  selectCategory (category) {
       this.category = category.category;
   }
  
   available(boolean){
  
    this.availability = boolean;
    }
  
    update($event){
      this.homeService.getByParm(this.availability,this.category).subscribe(data => {
        this.home = data;
      }); 
  
    }
    updateProduct = new FormGroup({
      id: new FormControl(''),
      productName: new FormControl(''),
      category: new FormControl(''),
      fullPrice: new FormControl(''),
      salePrice: new FormControl(''),
      availability: new FormControl(''),
      supplier: new FormControl(''),
      discount: new FormControl(''),

    });

// model = {id: null, productName: '', category: {category: null, categoryName: null}, fullPrice: '', salePrice:'', availability: false, supplier: {supplier:null,supplierName:""},discount:null};
// json = JSON.stringify(this.model);
constructor(private homeService: HomeService,private supplierService: SupplierService,private categoryService: CategoryService) { }
 

SortPrice($event:any){
  let icon = document.getElementById("asc-desc1");
  if(icon.className === "fas fa-angle-down"){
    icon.className ="fas fa-angle-up";
    this.homeService.getByPriceAsc().subscribe(data => {
    this.home = data;
  });
  }else{
    icon.className ="fas fa-angle-down"
    this.homeService.getByPriceDesc().subscribe(data => {
      this.home = data;
    });
  };
  
}
// model = new Newproduct(null,new Category( this.value,"name"),null,null,false,new Supplier(null,null),null);


onSubmit() {
  // TODO: Use EventEmitter with form value
  // console.warn(this.profileForm.value);
}
SortSale($event:any){
  let icon = document.getElementById("asc-desc2");
  if(icon.className === "fas fa-angle-down"){
    icon.className ="fas fa-angle-up";
    this.homeService.getBySaleAsc().subscribe(data => {
    this.home = data;
  });
  }else{
    icon.className ="fas fa-angle-down"
    this.homeService.getBySaleDesc().subscribe(data => {
      this.home = data;
    });
  };
  
}
SortDiscount($event:any){
  let icon = document.getElementById("asc-desc3");
  if(icon.className === "fas fa-angle-down"){
    icon.className ="fas fa-angle-up";
    this.homeService.getByDiscountAsc().subscribe(data => {
    this.home = data;
  });
  }else{
    icon.className ="fas fa-angle-down"
    this.homeService.getByDiscountDesc().subscribe(data => {
      this.home = data;
    });
  };
  
}


ngOnInit() {
  this.supplierService.getAll().subscribe(data => {
    this.suppliers = data;
  });
  
    this.homeService.getAll().subscribe(data => {
    this.home = data;
  });
  this.categoryService.getAll().subscribe(data => {
    this.categories = data;
  });
  
}

}

图片

Don't mix up the the Template Driven the Reactive Forms. You can read more info here .

As you are using 3 APIs in the same view, you can wait for all of them to respond then do the logic you want. This can be done by setting the observables into an object (an array for rxjs < 6.5) and use the forkJoin

const observables = {
  suppliers: this.supplierService.getAll(),
  home: this.homeService.getAll(),
  categories: this.categoryService.getAll()
};

forkJoin(observables).subscribe({ suppliers, home, categories } => {
  this.suppliers = suppliers;
  this.home = home;
  this.categories = categories;
});

After that, update the form using the patchValue:

updateProfile() {
  this.updateProduct.patchValue({
    id: this.home.id,
    productName: this.home.productName,
    category: this.home.category,
    fullPrice: this.home.fullPrice,
    salePrice: this.home.salePrice,
    availability: this.home.availability,
    supplier: this.home.supplier,
    discount: this.home.discount
  });
}

last thing, remove the selected and add a value for the options so it can select it after patching the value (It would be better of you have an id for the categories to set them as value)

<select class="form-control" formControlName="category" >
  <option [value]="home.category.categoryName" class="opt1" >{{home.category.categoryName}}</option>
  <option [value]="category.categoryName" *ngFor="let category of categories">{{category.categoryName}}</option>
</select>

Now when you want to submit, you can read the values through the form:

const formValues = this.updateProduct.value;
// This will contains all the values, you can access them by formValues.firstName ...etc

For more info for the Reactive Forms, you can check it here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM