ngModel从另一个对象获取值

时间:2018-02-17 16:54:26

标签: angular autocomplete

我有一个包含几行输入的组件。您可以添加和删除这些行。每行中的第一个输入是自动完成输入。它是使用子组件构建的,它将对象发送到父组件,而父组件将此对象的各个部分分开到不同的输入。问题是:当我在自动完成输入中选择新值时,前一行的二级输入会改变它们的值,但是它们不应该。

父组件:

@Component({
  selector: 'app-sale-add',
  template:
  "
    <div *ngFor="let product of list_of_products; index as i" class="row m-3">
      <div class="col-5">
        <app-product-search
          (chosenProduct)="chosenProduct($event, i)"
          [product]="product.product">
        </app-product-search>
      </div>
      <div *ngIf="product.product.retail_price" class="col-2">
        <input type="text" class="form-control" [(ngModel)]="list_of_products[i].product.retail_price" name="retail_price">
      </div>
      <div *ngIf="product.product.retail_price" class="col-2">
        <input type="number" class="form-control" min="1" [(ngModel)]="list_of_products[i].quantity" name="quantity">
      </div>
      <div class="col-2">{{ product.quantity }} | {{ i }}</div>
    </div>

  ",
styleUrls: ['./sale-add.component.css']
})
export class SaleAddComponent implements OnInit {
  list_of_products: any;
  constructor() { }

  ngOnInit() {
    this.list_of_products = [{
      product: new Product(),
      quantity: 1
    }];
  }

  addProduct(): void {
    this.list_of_products.push({product: new Product(), quantity: 1});
    console.log(this.list_of_products);
  }

  chosenProduct(product: Product, i: number): void {
    Object.assign(this.list_of_products[i].product, product);
  }
}

@Component({
  selector: 'app-product-search',
  template: 
'
  <div id="search-component">
    <input #searchBox id="search-box" class="form-control"
         (keyup)="search(searchBox.value)"
         (blur)="searchTerms.next('')" value="{{ product.name }}"/>

  <ul class="search-result">
    <li *ngFor="let product of products$ | async" (click)="click(product)">
      {{ product.name }}
    </li>
  </ul>
</div>

',
  styleUrls: ['./product-search.component.css']
})
export class ProductSearchComponent implements OnInit {
  products$: Observable<Product[]>;
  @Input() product: Product;
  searchTerms = new Subject<string>();
  @Output() chosenProduct = new EventEmitter<Product>();

  constructor(private productService: ProductService) { }

  ngOnInit() {
    this.products$ = this.searchTerms.pipe(
      debounceTime(300),
      distinctUntilChanged(),
      switchMap((term: string) => this.productService.searchProductByName(term))
    );
  }

  search(term: string): void {
    this.searchTerms.next(term);
  }

  click(product: Product): void {
    this.chosenProduct.emit(product);
    this.searchTerms.next('');
  }
}

1 个答案:

答案 0 :(得分:0)

没有找到一个好的解决方案,临时做了这个:

<div *ngFor="let product of list_of_products; index as i" class="row m-3">
  <div class="col-5">
    <app-product-search
      (chosenProduct)="chosenProduct($event, i)"
      [product]="product.product">
    </app-product-search>
  </div>
  <div *ngIf="product.product.retail_price" class="col-2">
    <input type="text" #price class="form-control"
           [value]="product.product.retail_price"
           (keyup)="product.product.retail_price = +price.value">
  </div>
  <div *ngIf="product.product.retail_price" class="col-2">
    <input type="number" #quantity class="form-control"
           min="1" [value]="product.quantity"
           (change)="product.quantity = +quantity.value"
           (keyup)="product.quantity = +quantity.value">
  </div>
  <div *ngIf="product.product.retail_price" class="col-1">
    <button type="button" class="btn btn-outline-danger"
            (click)="removeProduct(i)">X</button>
  </div>
</div>