我正在通过Vuex存储区中的axios从外部API获取数据,这给了我一个包含对象的数组-假设-cities
。
每个city
都有一个zipCode
,我需要使用它来获取城市详细信息。
我想将该详细信息对象添加为cities
数组的新键。
现在,我正在获取所有城市,并执行另一个Vuex操作以获取城市详细信息。
采取行动以获取所有城市
fetchCities: ({ commit, state, dispatch }) => {
let baseUrl = "https://my-url/cities";
let config = {
headers: {
accept: "application/json",
Authorization: ...
},
params: {
param1: "a",
param2: "b"
}
};
axios
.get(baseUrl, config)
.then(function(response) {
commit("UPDATE_CITIES_RAW", response.data.items);
})
.catch(function(error) {
console.log(error);
});
dispatch("fetchCityDetails");
},
获取所有城市后的静音
UPDATE_CITIES_RAW: (state, payload) => {
state.citiesRaw = payload;
},
该数组中的每个对象都有一个zipCode
,我正在使用它来获取有关这座城市的详细信息。
我尝试在操作内部循环citiesRaw
数组以获取详细信息并为每次迭代提交更改,但是此时状态数组为空,因为突变发生前必须采取行动。
采取行动以获取城市详细信息
fetchCityDetails: ({ commit, state }) => {
let baseUrl = "https://my-url/cities/"
let config = {
headers: {
accept: "application/json",
Authorization: ...
}
};
// citiesRaw is empty at this point
state.citiesRaw.forEach(e => {
let url = baseUrl + e.zipCode;
axios
.get(url, config)
.then(function(response) {
commit("UPDATE_CITY_DETAILS", {
response: response.data,
zipCode: e.zipCode
});
})
.catch(function(error) {
console.log(error);
});
});
},
等待第一次提取然后更新阵列的最佳方法是什么?
我应该使用相同的数组还是创建一个新的数组?
还是基于Vuex存储中获取的数据甚至有更好的获取方法?
更新
修复了异步功能甚至还没完成(感谢@ Y-Gherbi)之前的调度之后,我还重构了获取详细信息的方式:
fetchCities
fetchCities
操作中:提交UPDATE_CITIES
UPDATE_CITIES
突变:在有效负载上映射.map并创建新对象->将所有内容推送到state.cities
fetchCities
操作中:为每个城市循环state.cities
并调度fetchCityDetails(zipCode)
fetchCityDetails
操作中:提交UPDATE_CITY_DETAILS
UPDATE_CITY_DETAILS
突变中:在state.cities
上映射。并将cityDetails
对象添加到所引用的城市对象新动作
fetchCities: ({ commit, state, dispatch }) => {
let baseUrl = "https://my-url/cities";
let config = {
headers: {
accept: "application/json",
Authorization: ...
},
params: {
param1: "a",
param2: "b"
}
};
let url = baseUrl;
axios
.get(url, config)
.then(function(response) {
commit("UPDATE_CITIES", response.data.items);
state.cities.forEach(city => {
dispatch("fetchCityDetails", city.zipCode);
});
}
})
.catch(function(error) {
console.log(error);
});
},
fetchCityDetails: ({ commit }, zipCode) => {
let baseUrl = "https://my-url/cities";
let config = {
headers: {
accept: "application/json",
Authorization: ...
},
};
let url = baseUrl + "/" + zipCode;
axios
.get(url, config)
.then(function(response) {
commit("UPDATE_CITY_DETAILS", {
cityDetails: response.data,
zipCode: zipCode
});
})
.catch(function(error) {
console.log(error);
});
}
新突变
UPDATE_CITIES: (state, cities) => {
// I don't need all data & I want to rename the keys from the response,
// so I create a new object
cities = cities.map(city => {
let obj = {};
obj.zipCode = city.zip_code
obj.key1 = city.key_1;
obj.key2 = city.key_2;
return obj;
});
state.cities.push(...cities);
},
UPDATE_CITY_DETAILS: (state, payload) => {
let cities = state.cities;
// add one details-object for each city
cities = cities.map(city => {
if (city.zipCode == payload.zipCode) {
city.cityDetails = payload.cityDetails;
}
return city;
});
state.cities = cities;
}
问题仍然存在:是否有更好/更优化的方法来进行这种获取?
答案 0 :(得分:2)
我认为,有很多更好,更优雅的方法来解决这个问题,而只是简单地帮助您解决错误(遍历可能是城市阵列的空数组)
修复
尝试将commit函数移至下一行。 array
(citiesRaw
)为空,因为您在获取数据之前调用了该操作(因为axios.get
是异步的)
替代解决方案
正如您所说,城市将显示在具有可扩展行的表格中,这些行用于显示城市详细信息。获取100-1000个城市的数据很多,但这仍然是后端的一个电话。但是,从性能和带宽(如果这是大数据使用的正确术语)的角度来看,遍历所有这些项目并对每个项目都进行请求可能会出现问题。
我个人会在用户实际需要此数据时处理每个请求。在您的情况下,只要用户单击一行以展开它即可。
将其存储在商店中吗?
何时要在商店中存储城市详细信息取决于您。您可以将其保留在组件中,但就我个人而言,我会将其用作某种缓存机制。
当用户单击一行时,检查详细信息是否已获取
if(!state.cityDetails[key]) {
axios.get().then(res => {
// Commit a mutation that saves the fetched details
})
} else {
// Use the 'cached' cityDetails
}
您的商店可能看起来像这样:
{
cityDetails: {
'keyCouldBeIdOrZipcode': {...},
'anOtherAlreadyFetchedCity': {...}
}
}
很抱歉输入错误和格式错误。在手机上输入代码太可怕了