3

我正在构建一个 React+Reflux 应用程序,除其他外,它允许创建/删除/编辑类别。到目前为止,我能够显示所有类别并通过关联的存储和操作在 React 组件中处理类别的创建/删除。这一切都很好,更新数据库并按预期重新渲染组件。我的症结在于试图深入研究特定的现有类别以对其进行编辑。

我需要以某种方式将类别 ID 传递给商店,然后商店将通过 ajax 调用将其传递给 php/sql 查询,以便获取/设置特定于该特定类别的数据。如果我完全绕过商店并将ajax调用放在组件本身中,我可以通过带有React-router的url参数让它工作(当然没有自动重新渲染)但我无法弄清楚如何通过商店做到这一点。

换句话说,这或多或少有效:

  • “ManageCategories” React 组件,它使用 CategoryStore 列出所有类别,每个类别都包含在一个锚标记中,该锚标记将类别 ID 传递给“ManageCategory”路由/组件
  • “ManageCategory”组件在其 getInitialState 方法内的 ajax 调用中直接使用类别 ID 参数来显示特定于类别的数据

但是,我认为下面是更正确的 Reflux 方法,但我不确定如何让它工作:

  • “ManageCategories”组件同上
  • “ManageCategory”组件以某种方式将其类别 ID 参数传递给 CategoryStore(或者可能是不同的“IndividualCategoryStore”?),该组件仅返回特定于该类别的数据并处理对该类别的更新/编辑

通过向 CategoryStore 添加一个新方法(“getCategoryData”),该方法在“ManageCategory”组件的 getInitialState 方法中调用并传递了 categoryId 参数,我能够获得这种工作的一种笨重版本。这会导致所有类别(来自 CategoryStore 的 getDefaultData)的闪烁,然后是正确的单个类别列表(来自组件的 getInitialState)。

我对 React+Reflux 背后的概念感到相当满意,但在这一点上,我认为我可能误解了一些基本的东西。在这个特定问题上工作了一个多星期,但我发现的示例/教程/文档都没有解决将变量传递到数据存储的具体问题。

行动:

var Actions = Reflux.createActions([
"createCategory",
"deleteCategory",
"editCategory"
]);

分类商店:

var CategoryStore = Reflux.createStore({
listenables: [Actions],
onCreateCategory: function(catName) {
    // ajax call to create new category that calls updateCategories on success
},
onDeleteCategory: function(catId) {
    // ajax call to delete category that calls updateCategories on success
},
updateCategories: function(){
    $.ajax({
        url: url + '?action=getAllCategories',
        async: false,
        dataType: 'json',
        success: function(categoryData) {
            this.categories = categoryData;
        }.bind(this),
        error: function(xhr, status, err) {
            console.error(url, status, err.toString());
        }.bind(this)
    });
    this.trigger(this.categories);
},
getDefaultData: function() {
    $.ajax({
        url: url + '?action=getAllCategories',
        async: false,
        dataType: 'json',
        success: function(categoryData) {
            this.categories = categoryData;
        }.bind(this),
        error: function(xhr, status, err) {
            console.error(url, status, err.toString());
        }.bind(this)
    });
    return this.categories;
}
});

类别组件:

var Category = React.createClass({
handleDeleteCategory: function() {
    Actions.deleteCategory(this.props.id);
},
render: function() {
    return (
        <li className="category">
            <IconButton icon="action-highlight-remove" onClick={this.handleDeleteCategory} />
            <h5><a href={"/#/manage-category/" + this.props.id}>{this.props.name} ({this.props.id})</a></h5>
        </li>
    );
}
});

管理类别组件:

var ManageCategories = React.createClass({
mixins: [
    Reflux.connect(CategoryStore, "categories")
],
getInitialState: function() {
    return {
        categories: []
    };
},
handleCreateCategory: function() {
    // category creation code
},
render: function() {
    var categoryNodes = this.state.categories.map(function(category) {
        return (
            <Category name={category.name} id={category.id} />
        )
    });
    return (
        <div className="dev-tools-container">
            <h1>Developer Tools</h1>
            <div className="categories">
                <h3>Categories</h3>
                <ul>
                    {categoryNodes}
                </ul>
                <h4>Create New Category:</h4>
                <form>
                    <label htmlFor="new-category-name">Category Name</label> <input type="text" id="new-category-name" /><br />
                    <PaperButton label="Create" primary={true} onClick={this.handleCreateCategory} />
                </form>
            </div>
        </div>
    );
}
});

提前感谢您的任何见解或帮助。

4

1 回答 1

3

在终于在这里发布我的问题之后,我想我可能已经弄清楚我一直误入歧途了。我正在考虑将类别 ID 传递给商店以过滤其中的数据,而我真正需要做的就是从商店中获取完整的数据集合并在组件中选择性地使用它。

因此,一旦将 catId 作为 url 参数传递到 ManageCategory 组件,我需要做的就是根据 catId 过滤数据。

例如,在 ManageCategory 组件中,我可以使用 lodash 过滤和提取当前类别的名称值,如下所示。根本不需要编辑存储在 CategoryStore 中的数据集合。

var ManageCategory = React.createClass({
mixins: [
    Reflux.connect(CategoryStore, "categoryData")
],
getInitialState: function() {
    return {
        categoryData: []
    };
},
render: function() {
    var categoryName = _.chain(this.state.categoryData)
                        .filter({"id": this.props.params.catid})
                        .pluck("name");

    return (
        <div className="category-container">
            <h1>{categoryName}</h1>
        </div>
    );
}
});

如果有更好的方法可以随时告诉我,但现在这正是我所需要的。希望所有这些中的一些东西也对其他人有所帮助。

于 2014-12-22T20:41:20.520 回答