Dan*_*mov 7 architecture json nested flux cqrs
我正在将一个现有的应用程序移植到Flux,我对一个主题感到有些困惑.假设我有几个返回两级或三级嵌套对象的API端点.
例如,GET /articles可以返回架构的JSON响应
articles: article*
article: {
author: user,
likers: user*
primary_collection: collection?
collections: collection*
}
collection: {
curator: user
}
Run Code Online (Sandbox Code Playgroud)
如您所见,不同级别的嵌套有各种各样的用户:
articles[i].authorarticles[i].likers[i]articles[i].primaryCollection.curatorarticles[i].collections[i].curator如果我想在UserStore任何时候获取文章时使用新数据进行更新,我必须编写一个怪异的方法来检查文章API响应中的所有嵌套实体.此外,会有很多重复,因为还有其他API端点具有不同的模式,有时文章嵌入在用户内(例如GET /user/published).
Flux商店是否有更清晰的方法从所有API响应中提取嵌套实体?
Jing Chen(Flux创作者和传播者之一)提出的一种方法是在API响应到达商店之前将其平铺.我写了一个小型库,它就是这样做的:它正常化了
[{
id: 1,
title: 'Some Article',
author: {
id: 1,
name: 'Dan'
}
}, {
id: 2,
title: 'Other Article',
author: {
id: 1,
name: 'Dan'
}
}]
Run Code Online (Sandbox Code Playgroud)
至
{
result: [1, 2],
entities: {
articles: {
1: {
id: 1,
title: 'Some Article',
author: 1
},
2: {
id: 2,
title: 'Other Article',
author: 1
}
},
users: {
1: {
id: 1,
name: 'Dan'
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
(注意没有重复,结构是平的.)
Normalizr让您:
要使用它,您需要定义实体和嵌套规则并使用它们来转换JSON:
var normalizr = require('normalizr'),
normalize = normalizr.normalize,
Schema = normalizr.Schema,
arrayOf = normalizr.arrayOf;
// First, define a schema:
var article = new Schema('articles'),
user = new Schema('users'),
collection = new Schema('collections');
// Define nesting rules:
article.define({
author: user,
collections: arrayOf(collection)
});
collection.define({
curator: user
});
// Usage:
// Normalize articles
var articlesJSON = getArticleArray(),
normalized = normalize(articlesJSON, arrayOf(article));
// Normalize users
var usersJSON = getUsersArray(),
normalized = normalize(usersJSON, arrayOf(user));
// Normalize single article
var articleJSON = getArticle(),
normalized = normalize(articleJSON, article);
Run Code Online (Sandbox Code Playgroud)
这允许您在将任何XHR响应传递给Flux Dispatcher之前对其进行标准化.商店只需要从相应的字典中更新自己:
// UserStore
UserStore.dispatchToken = AppDispatcher.register(function (payload) {
var action = payload.action;
switch (action.type) {
// you can add any normalized API here since that contains users:
case ActionTypes.RECEIVE_ARTICLES:
case ActionTypes.RECEIVE_USERS:
// Users will always be gathered in action.entities.users
mergeInto(_users, action.entities.users);
UserStore.emitChange();
break;
}
});
// ArticleStore
AppDispatcher.register(function (payload) {
var action = payload.action;
switch (action.type) {
// you can add any normalized API here since that contains articles:
case ActionTypes.RECEIVE_ARTICLES:
// Wait for UserStore to digest users
AppDispatcher.waitFor([UserStore.dispatchToken]);
// Articles will always be gathered in action.entities.articles
mergeInto(_articles, action.entities.articles);
ArticleStore.emitChange();
break;
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1996 次 |
| 最近记录: |