0

我的 HTML 文件中有以下按钮:

<td width="75%" colspan="2">
   <button mat-raised-button color="primary" type="button" style='margin-right:5px' style='margin-left:auto' (click)="openAddProductDialog()">Add Product</button>
</td>

以及以下下拉菜单:

<td colspan="2" width="100%">
    <mat-form-field class="generate-full-width">
        <mat-select placeholder="Product" formControlName="product" name="product" (selectionChange)="getDefaultValues()">
            <mat-option *ngFor="let product of products" [value]="product.value">
                                    {{product.viewValue}}
            </mat-option>
        </mat-select>
        <mat-error *ngIf="submitted && hasError('product', 'required')">Product is required</mat-error>
    </mat-form-field>

单击此按钮时,将打开一个对话框,其中包含以下 HTML 文件:

form [formGroup]="form" (ngSubmit)="addProduct(form)">
  <h1 mat-dialog-title color="primary">Add Product</h1>
  <mat-dialog-content >
      <div style="width:100%;display: flex;flex-direction: column;">
    <mat-form-field>
      <input matInput formControlName="productId" placeholder="Enter the Product Name">
      <mat-error *ngIf="submitted && hasError('productId', 'required')">Product Name is required</mat-error>
    </mat-form-field>
    <mat-form-field>
      <input matInput formControlName="instances" placeholder="Enter Instances" numbersOnly>
      <mat-hint>Allow only numeric values</mat-hint>
    </mat-form-field>
</mat-dialog-actions>
</form>

有一个提交按钮,可以将产品保存到数据库中。现在每次我都必须刷新网页,以便新添加的产品反映在主窗体的下拉列表中。由于某些限制,无法将 Live Reload 添加到 Web 浏览器。我尝试使用 onEvent 和 ngModel 但几乎破坏了应用程序。请帮我解决一下这个。

以下是添加产品的组件:

@Component({
  selector: 'add-product-dialog',
  templateUrl: 'add-product-dialog.html',
})
export class AddProductDialog implements OnInit {
  form: FormGroup;
  submitted: boolean = false;
  constructor(
    private fb: FormBuilder,
    public dialogRef: MatDialogRef<AddProductDialog>,
    private generateService: GenerateService,
    @Inject(MAT_DIALOG_DATA) public data) {
  }

  ngOnInit() {
    this.form = this.fb.group({
      productId: ['', Validators.required],
      instances: ['']
    });
  }
  // add product 
  addProduct(form: FormGroup) {
    this.submitted= true;
    const { value, valid } = this.form;
    let productId = this.form.value.productId;
    let instances = this.form.value.instances;
    this.generateService.addNewProduct(productId, instances)
    .subscribe((data) => {
      console.log(data)
    })
    console.log(value)
    if (valid) {
      this.dialogRef.close(value);
    }

  }
  // validation for input fields
  public hasError = (controlName: string, errorName: string) => {
    return this.form.controls[controlName].hasError(errorName);
  }

}

以下是对话框:

openAddProductDialog(): void {
    const dialogRef = this.dialog.open(AddProductDialog, {
      width: '450px',
      disableClose: true,
      autoFocus: true
    });

ngOnInit() {
    this.createForm();
    this.generateService.getProducts()
    .subscribe((data) => {
      console.log(data)
      this.allProducts = data;
      this.allProducts.forEach(element => {
        this.products.push({
          "value" : element["productId"],
          "viewValue" : element["productId"]
        })
        
      });
    });
    this.getDefaultConfig();
  }

    dialogRef.afterClosed().subscribe(result => {
      console.log('The dialog was closed');
    });
  }

这是主要形式。如果需要,可以提供任何其他信息。

在 service.ts 中为 addProduct 和 getProduct 添加组件:

addNewProduct(product: string, instances : number) {
    let headers = new HttpHeaders({
      'Content-Type': 'application/json'
    })

    let options = {headers:headers, observer: 'response'};

    let data = {
        "productId" : product,
        "instances" : instances
    }
let result : Observable<Object>= this.http.post(this.url+'/product/add',data,options);
    console.log("service response------>")
    return result;
  }

getProducts() {
    let headers = new HttpHeaders({
      'Content-Type': 'application/json'
    })

    let options = {headers:headers, observer: 'response'};
    let result : Observable<Object> = this.http.get(this.url+'/product/list',options);
    console.log(result);
    return result;

  }
4

1 回答 1

0

有两种类型的变化。

  • 另一个用户所做的更改,在这种情况下,您需要像 sockets.io、SignalR 等一样让服务器在数据库更改发生时向您发送通知。

  • 同一用户所做的更改,这是下一个建议的内容。

您可以创建一个名为例如的服务ProductsService

@Injectable({
    providedIn: 'root'
})
export class ProductsService implements OnDestroy {
    // Subject to cache product list
    private readonly _products$ = new BehaviorSubject<Product[]|null>(null);
    // This observable will fetch from the database if the product are not already fetched
    // And will return the currently cached product list otherwiser
    public readonly products$ = this._products$.pipe(
        switchMap((p) => p === null ? this.getProducts() : of(p))
    );
    
    // On destroy call complete on the observable making sure all subscribers are unsubscribed.
    public ngOnDestroy(): void {
        this._products$.complete();
    }

    // Get products call getProductsFromDatabase and and uses tap to cache the returned data.
    public getProducts(): Observable<Product[]> {
        return this.getProductsFromDatabase()
            .pipe(
                tap((res) => this._products$.next(res)),
            );
    }
    
    // get products from database
    public getProductsFromDatabase(): Observable<Product[]> {
        // Code to fetch products from database here.
        return of([]);
    }

    // Add product that should be called by dialog component
    public async addProduct(newProduct: Product): Promise<void> {
        // Update the new product option id property to that returned from database.       
        newProduct.id = await this.saveProductToDatabase(newProduct);
        // Add product to cached product list.
        const currentProducts = this._products$.value || [];
        currentProducts.push(newProduct);
        // emit the next change to products$, will cause components subscribing to get new value
        this._products$.next(currentProducts);
    }

    // This performs actual request to save product to database.
    // In case the database will generate an id for the product, return it.
    public async saveProductToDatabase(newProduct: Product): Promise<string> {
        // Code to save new product to database.
        // return the product id in case the 
    }
}

现在您的页面和对话框组件都应该引用此服务。您的对话框组件应调用addProduct以将产品保存到数据库。

您的选择应该从product$可观察和使用的async管道中选择,该管道将订阅更改并更新选择。

 <mat-option *ngFor="let product of productService.products$ | async" [value]="product.value">
                                {{product.viewValue}}
 </mat-option>
于 2020-09-08T18:44:02.960 回答