【发布时间】:2020-09-21 16:19:55
【问题描述】:
我有一个计算属性 (filteredMeasurementsByAttribute),它应该提供数据属性的过滤版本 (measurementsByAttribute)。但是,计算属性的更改也发生在数据属性上。
过滤器使用 selectedAttributes 中的数据(前端下拉列表中选择的选项),然后在 measurementsByAttribute。此过滤器工作正常。问题是当我运行从 selectedAttributes 中清除数据的 clearAttribute 方法时(这部分工作成功) measurementsByAttribute 属性是过滤后的版本,所以我无法取回旧数据。
简而言之,我想保留 measurementsByAttribute 属性的原始版本,以便清除 selectedAttributes 属性,并为 filteredMeasurementsByAttribute 重置下拉表单提供所有原始数据。
我尝试将数据保存在常规 javascript 变量 measurementsByAttributeMaster 中,然后设置 measurementsByAttribute 给主人。不知何故,它们最终都只有过滤后的值。
我尝试更改循环数据的方式(例如,使用 forEach 而不是过滤器或映射)只是为了查看它是否会导致它编辑原始数据。没运气。我在注释掉的代码中保留了使用过滤器和映射的“原始”版本,因此您可以看到这两个版本。
非常感谢任何见解或帮助。
/**
* Select Product
*/
function filterMeasurements(attribute, measurementsAvailable) {
var filteredMeasurements = [];
attribute.measurements.forEach(function(measurement) {
if (measurementsAvailable.includes(measurement.id.toString())) {
filteredMeasurements.push(measurement);
}
});
// return attribute.measurements.filter(function(measurement) {
// return measurementsAvailable.includes(measurement.id.toString());
// });
return filteredMeasurements;
}
/**
* Check if the part matches the selected Attributes
*
* @param {array} selectedAttributes Array of all the currently selected attributes
* @param {object} part The part we are checking
* @retrun {array} the fitlered selectedAttributes
*/
function checkPartAttributes(selectedAttributes, part) {
var partAttributes = JSON.parse(part.attributes_json);
// Loop through each selected attribute to ensure there aren't any conflicts
return selectedAttributes.every(function(measurementID, attributeID) {
// if no measurement has been selected, it is acceptable
if (measurementID == "") {
return true;
}
// if the part does have this attribute, it needs to match
if (attributeID in partAttributes) {
return partAttributes[attributeID] == measurementID;
}
console.log('here');
// If the part doesn't have this attribute, it is acceptable
return true;
});
}
// var SelectSpecifications = require('./components/SelectProduct/SelectSpecifications.vue');
var vm = new Vue({
el: '#select-product',
components: {
SelectSpecifications
},
data () {
return {
allParts: allParts,
measurementsByAttribute: measurementsByAttribute,
selectedAttributes: selectedAttributes,
}
},
computed: {
/**
* combine all the attributes from the matching parts
*
* @return {array} The filtered attributes
*/
filteredAttributes: function() {
var filteredAttributes = JSON.parse("{}");
console.log('filteredAttributes');
// loop through each matching part and create new array of the matching attributes
this.matchingParts.forEach(function(part) {
var partAttributes = JSON.parse(part.attributes_json);
for (attributeID in partAttributes) {
// Add to the index if already exists
if (attributeID in filteredAttributes) {
filteredAttributes[attributeID].push(partAttributes[attributeID]);
filteredAttributes[attributeID] = [...new Set(filteredAttributes[attributeID])];
// create the index if it doesn't already exist
} else {
var tempArr = [partAttributes[attributeID]];
filteredAttributes[attributeID] = tempArr;
}
}
});
return filteredAttributes;
},
/**
* filter the measurements by selected values
* @return {object} All the filtered measurements sorted by attribute
*/
filteredMeasurementsByAttribute: {
get: function() {
console.log('filteredMeasurementsByAttribute');
var selected = this.selectedAttributes;
var filteredMeasurementsByAttribute = [];
var filteredAttributesKeys = Object.keys(this.filteredAttributes);
var filteredAttributes = this.filteredAttributes;
this.measurementsByAttribute.forEach(function (attribute, index) {
console.log(attribute);
var tempAttribute = attribute;
// filteredMeasurementsByAttribute[index] = tempAttribute;
if (filteredAttributesKeys.includes(tempAttribute.id.toString())) {
var filteredMeasurements = filterMeasurements(tempAttribute, filteredAttributes[tempAttribute.id]);
tempAttribute.measurements = filteredMeasurements;
filteredMeasurementsByAttribute[index] = tempAttribute;
}
});
// return measurementsByAttribute.map(function(attribute) {
// if (filteredAttributesKeys.includes(attribute.id.toString())) {
// attribute.measurements = filterMeasurements(attribute, this.filteredAttributes[attribute.id]);
// return attribute;
// }
// }, this);
return filteredMeasurementsByAttribute;
},
set: function(newMeasurementsByAttribute) {
console.log('setter working!');
this.measurementsByAttribute = newMeasurementsByAttribute;
}
},
// returns matching parts depending on what attributes are selected
matchingParts: function() {
console.log('matchingParts');
return this.allParts.filter(checkPartAttributes.bind(this, this.selectedAttributes));
},
},
methods: {
clearAttribute: function(attributeID) {
this.$set(this.selectedAttributes, attributeID, "");
var tempArray = [];
this.filteredMeasurementsByAttribute = tempArray.concat(measurementsByAttributeMaster);
// this.selectedAttributes.splice(0);
},
kebabTitle: function(title) {
if (title == null) {
return '';
}
return title.replace(/([a-z])([A-Z])/g, "$1-$2")
.replace(/\s+/g, '-')
.toLowerCase();
},
}
});
【问题讨论】:
标签: javascript vue.js