javascript - 对象同步

标签 javascript angular typescript

我的 angular4 应用程序中发生了一件非常奇怪的事情,我一生都无法弄清楚。

本质上我是

  1. 将完整的产品和商品列表加载 (@Input) 到名为产品的对象中。
  2. 在名为实体的对象中加载 (@Input),该对象包含产品属性以及完整产品列表的子集,即仅用户已保存到实体中的产品。
  3. 加载产品数据 - 我将每个产品从 this.products 推送到 ProductSelectionData
  4. 然后,我运行一个函数,循环遍历productSelectionData 中的所有项目,并检查实体对象中是否有任何具有名为 selected 的属性的项目,并将 selected 的值更改为 true

此时一切看起来都很好

  • 然后,我运行一个函数来拼接 selectedProducts 和 selected 属性为 false 的项目。
  • 这就是问题发生的地方。由于某种原因,这对我来说并不明显,productSelectionData 对象和 selectedProducts 对象都将 selected = false 的项目从数组中拼接出来。

    代码如下:

    import { Component, Input, OnInit } from '@angular/core';
    import { ProposalModel, ProductModel } from './../../../shared/models/';
    
    @Component({
      selector: 'mj-proposal-edit',
      templateUrl: './proposal-edit.component.html',
      styleUrls: ['./proposal-edit.component.scss']
    })
    export class ProposalEditComponent implements OnInit {
    
      @Input() entity: ProposalModel;
      @Input() products: ProductModel[];
    
      productSelectionData: any;
      selectedProducts: any;
    
      constructor() { }
    
      ngOnInit() {
    
        // Load all products and items
        this.loadProductData();
        this.updateProductSelectionData();
        this.filterProductsSelected();
    
      }
    
      loadProductData() {
        this.productSelectionData = [];
    
        this.products.forEach(product => {
          this.productSelectionData.push(
            { productTitle: product.productTitle, items: product.items })
        });
        console.log('Product Selection, after load: ', this.productSelectionData);
        debugger;
      }
    
      updateProductSelectionData() {
        // Update Product Selection Object with previously selected data
    
        // 1. Check if there is previously saved data
        if (this.entity.products !== undefined) {
          // 2. Update productSelectionData with values saved in entity object
          this.productSelectionData.forEach(product => {
            if (this.entity.products !== undefined) {
              this.entity.products.forEach(entityProduct => {
                if (product.productTitle === entityProduct.productTitle) {
                  if (product.items !== undefined) {
                    product.items.forEach(item => {
                      if (entityProduct.items !== undefined) {
                        entityProduct.items.forEach(entityItem => {
                          if (item.code === entityItem.code) {
                            item.selected = true;
                            item.quantity = entityItem.quantity;
                            item.discount = entityItem.discount;
                          }
                        });
                      }
                    });
                  }
                }
              });
            }
          });
          console.log('Product Selection, after update: ', this.productSelectionData);
          debugger;
        }
      }
    
      filterProductsSelected() {
        this.selectedProducts = [];
        this.productSelectionData.forEach(product => {
          this.selectedProducts.push(product)
        });
        this.selectedProducts.forEach(selectedProduct => {
          selectedProduct.items.forEach(item => {
            const itemIndex = selectedProduct.items.indexOf(item);
            if (item.selected === false) {
              selectedProduct.items.splice(itemIndex, 1);
            }
            if (item.selected === undefined) {
              selectedProduct.items.splice(itemIndex, 1);
            }
          });
        });
        console.log('Selected Products, after filter: ', this.selectedProducts);
        console.log('Product Selection, after filter: ', this.productSelectionData);
        debugger;
      }
    
    }
    

    最佳答案

    在 filterProductsSelected 中,您将产品(及其 items 数组)推送到 this.selectedProducts 数组中。

    您最终会在 this.selectedProductsthis.productSelectionData 中引用您的产品及其项目

    所以,当你在这里拼接时: selectedProduct.items.splice(itemIndex, 1);

    您正在拼接同一个 items 数组。

    我克隆了产品对象及其项目数组,它似乎有效:

    function filterProductsSelected() {
        selectedProducts = [];
        productSelectionData.forEach(product => {
          // cloning the product :
          var productClone = clone(product);
          // and its items :
          productClone.items = product.items.slice();
          selectedProducts.push(productClone);
        });
        selectedProducts.forEach(selectedProduct => {
          selectedProduct.items.forEach(item => {
            const itemIndex = selectedProduct.items.indexOf(item);
            if (item.selected === false) {
                console.log("not selected");
              selectedProduct.items.splice(itemIndex, 1);
            }
            if (item.selected === undefined) {
                console.log("undefined selected");
    
            selectedProduct.items.splice(itemIndex, 1);
            }
          });
        });
        console.log('Selected Products, after filter: ', selectedProducts);
        console.log('Product Selection, after filter: ', productSelectionData);
        debugger;
      }
    

    克隆功能代码:

    function clone(obj) {
        if (null == obj || "object" != typeof obj) return obj;
        var copy = obj.constructor();
        for (var attr in obj) {
            if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
        }
        return copy;
    }
    

    关于javascript - 对象同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46806640/

    相关文章:

    javascript - 如何在 react 组件中切换 mousedown/mouseup 类?

    angular - 拖动后点击事件触发

    angular - 尽管主题接下来调用,但指令订阅不会触发

    javascript - 如何随机化 javascript Canvas 中的坐标?

    javascript - 如何使用 puppeteer 抓取多个页面

    javascript - 为什么来自用户脚本的窗口(和 unsafeWindow)与来自 <script> 标签的窗口(和 unsafeWindow)不同?

    angularjs - 如何从 Angular cli 调用 Passportjs(node) API?

    angular - ngx-select-dropdown 示例值未绑定(bind)

    json - 我如何在不知道 name 属性的对象数组中执行 *ngFor ?

    javascript - 为什么这段 JavaScript 代码在 TypeScript 中失败?