Javascript 同步对象

Javascript 同步对象,javascript,angular,typescript,Javascript,Angular,Typescript,在我的angular4应用程序中发生了一件非常奇怪的事情,我一辈子都搞不懂 基本上我是 将(@Input)在产品和项目的完整列表中加载到名为products的对象中 在名为entity的对象中加载(@Input),该对象包含具有完整产品列表子集的产品属性,即仅用户已保存到实体中的产品属性 加载产品数据-我将此.products中的每个产品推送到productSelectionData中 然后,我运行一个函数,在productSelectionData中的所有项之间循环,并检查实体对象中是否有名为

在我的angular4应用程序中发生了一件非常奇怪的事情,我一辈子都搞不懂

基本上我是

  • 将(@Input)在产品和项目的完整列表中加载到名为products的对象中
  • 在名为entity的对象中加载(@Input),该对象包含具有完整产品列表子集的产品属性,即仅用户已保存到实体中的产品属性
  • 加载产品数据-我将此.products中的每个产品推送到productSelectionData中
  • 然后,我运行一个函数,在productSelectionData中的所有项之间循环,并检查实体对象中是否有名为selected的属性,并将selected的值更改为true
  • 在这一点上,一切看起来都很好

  • 然后,我运行一个函数,将选定属性为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;
      }
    
    }
    

    在您的FilterProducts Selected中,您正在将产品(及其
    数组)推入您的
    this.selectedProducts
    数组

    this.selectedProducts
    this.productSelectionData
    中,您最终都会引用您的产品及其

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

    您正在拼接相同的
    项目
    数组

    我克隆了product对象及其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;
    }
    

    在您的FilterProducts Selected中,您正在将产品(及其
    数组)推入您的
    this.selectedProducts
    数组

    this.selectedProducts
    this.productSelectionData
    中,您最终都会引用您的产品及其

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

    您正在拼接相同的
    项目
    数组

    我克隆了product对象及其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;
    }
    

    哇,谢谢你。我刚刚学到了一些东西,我不知道。从一个物体推到另一个物体会产生一个参照物,我认为它的作用完全相反。在接下来的几天里,我将查看您的代码。再次感谢您的解释,谢谢。我刚刚学到了一些东西,我不知道。从一个物体推到另一个物体会产生一个参照物,我认为它的作用完全相反。在接下来的几天里,我将查看您的代码。再次感谢您的解释和代码