我正在使用Facebook的Flux Dispatcher創建一個簡單的CRUD應用程序來處理英語學習網站的帖子創建和編輯。我目前正在打交道的,看起來像這樣的API:如何在flux中處理嵌套的api調用
/posts/:post_id
/posts/:post_id/sentences
/sentences/:sentence_id/words
/sentences/:sentence_id/grammars
在節目中和編輯網頁的應用程序,我想能夠顯示所有信息特定職位以及所有的它的句子和句子的單詞和語法細節都在一個頁面上。
我遇到的問題是如何啓動所有收集所有這些數據所需的異步調用,然後將需要從所有商店獲得的數據組合到一個單獨的對象中,我可以將其設置爲狀態我的頂級組件。什麼,我一直試圖做一個電流(可怕的)例子是這樣的:
頂級PostsShowView:
class PostsShow extends React.Component {
componentWillMount() {
// this id is populated by react-router when the app hits the /posts/:id route
PostsActions.get({id: this.props.params.id});
PostsStore.addChangeListener(this._handlePostsStoreChange);
SentencesStore.addChangeListener(this._handleSentencesStoreChange);
GrammarsStore.addChangeListener(this._handleGrammarsStoreChange);
WordsStore.addChangeListener(this._handleWordsStoreChange);
}
componentWillUnmount() {
PostsStore.removeChangeListener(this._handlePostsStoreChange);
SentencesStore.removeChangeListener(this._handleSentencesStoreChange);
GrammarsStore.removeChangeListener(this._handleGrammarsStoreChange);
WordsStore.removeChangeListener(this._handleWordsStoreChange);
}
_handlePostsStoreChange() {
let posts = PostsStore.getState().posts;
let post = posts[this.props.params.id];
this.setState({post: post});
SentencesActions.fetch({postId: post.id});
}
_handleSentencesStoreChange() {
let sentences = SentencesStore.getState().sentences;
this.setState(function(state, sentences) {
state.post.sentences = sentences;
});
sentences.forEach((sentence) => {
GrammarsActions.fetch({sentenceId: sentence.id})
WordsActions.fetch({sentenceId: sentence.id})
})
}
_handleGrammarsStoreChange() {
let grammars = GrammarsStore.getState().grammars;
this.setState(function(state, grammars) {
state.post.grammars = grammars;
});
}
_handleWordsStoreChange() {
let words = WordsStore.getState().words;
this.setState(function(state, words) {
state.post.words = words;
});
}
}
這裏是我的PostsActions.js - 其他實體(句子,語法,字)也有類似的工作方式類似ActionCreators:
let api = require('api');
class PostsActions {
get(params = {}) {
this._dispatcher.dispatch({
actionType: AdminAppConstants.FETCHING_POST
});
api.posts.fetch(params, (err, res) => {
let payload, post;
if (err) {
payload = {
actionType: AdminAppConstants.FETCH_POST_FAILURE
}
}
else {
post = res.body;
payload = {
actionType: AdminAppConstants.FETCH_POST_SUCCESS,
post: post
}
}
this._dispatcher.dispatch(payload)
});
}
}
的主要問題是,流量調度將拋出時SentencesActions.fetch
是所謂的_handlePostsStoreChange
回調不變錯誤「無法在調度中間派遣」 becau如果SentencesActions方法在前一個操作的調度回調完成之前觸發一個調度。
我知道我可以通過使用像_.defer
或setTimeout
這樣的東西來解決這個問題 - 不過那真的覺得我只是在這裏修補問題。此外,我考慮在動作本身中執行所有這些獲取邏輯,但這似乎也不正確,並且會使錯誤處理更加困難。我將每個實體都分離到了自己的商店和行爲中 - 組件級別的組織不應該有某種方式來構建我需要從每個實體的各自商店購買的東西嗎?
對於任何已經完成類似事情的人的任何建議都是開放的!
你嘗試過使用'waitFor'嗎? https://facebook.github.io/flux/docs/dispatcher.html – knowbody
@knowbody是的,我試圖使用'waitFor',但它似乎並沒有真正解決這個問題,因爲問題是第二個動作會在第一個動作完成之前發送。但是,也許我對'waitFor'的理解是錯誤的,我只是沒有正確使用它? – joeellis
@joeellis:是否有可能將jsFiddle演示放在一起,展示您的問題情況? –