【发布时间】:2018-10-28 23:43:15
【问题描述】:
我正在通过 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");
},
获取所有城市后的MUTATION
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 - in
UPDATE_CITIES突变:.map 在有效负载上并创建新对象 -> 全部推送到state.cities - 在
fetchCities中操作:循环state.cities并为每个城市发送fetchCityDetails(zipCode) - 在
fetchCityDetails中操作:提交UPDATE_CITY_DETAILS - 在
UPDATE_CITY_DETAILS突变中:.map onstate.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;
}
问题仍然存在:对于这种获取,是否有更好/更优化的方法?
【问题讨论】:
-
你能显示整个 vuex 存储代码吗?
-
@BoussadjraBrahim 您还需要什么?只有一个甚至没有执行的突变丢失了。
-
我在尝试绑定你的代码 sn-ps 时掉线了,可能是因为我累了
-
尝试将调度函数移到提交函数之后的下一行。数组 (citiesRaw) 为空,因为您在获取数据之前调用操作(因为 axios.get 是异步的)
-
我在考虑更好的处理方法时遇到了一些问题。 1. 您是否需要在每个详细信息页面上同时只需要一个(或几个)所有城市详细信息或类似的东西? 2.后端提供多少个城市?有没有办法根据 userId 之类的东西来限制它?
标签: javascript vue.js vuejs2 axios vuex