2014-12-22 47 views
3

我正在構建一個React + Reflux應用程序,該應用程序允許創建/刪除/編輯類別。到目前爲止,我可以顯示所有類別,並通過關聯的商店和操作處理React組件內類別的創建/刪除。這一切都很好,更新數據庫並按預期重新渲染組件。我的堅持點是,當試圖深入到一個特定的現有類別,以編輯它。React + Reflux:將變量傳遞給數據存儲

認爲我不知何故需要傳遞一個類別ID到商店,然後將它通過ajax調用傳遞給php/sql查詢以獲取/設置特定於該特定類別的數據。如果我完全繞過商店並將ajax調用放在組件本身中,我可以通過使用React-router的url參數來工作(當然沒有自動重新渲染),但我一直無法弄清楚如何通過商店來實現這一點。

換句話說,這或多或少作品:

  • 「ManageCategories」響應使用CategoryStore列出所有類別的每個包裹在經過類別ID一起爲「ManageCategory」路線的錨標籤組件/部件
  • 的「ManageCategory」組件使用類別ID PARAM直接在其getInitialState方法內的AJAX調用以顯示特定的數據的類別

然而,我認爲下面是更正確的迴流WA Ÿ要做到這一點,但我不知道如何得到它的工作:

  • 「ManageCategories」組件同上
  • 「ManageCategory」,不知怎的,通過其類別ID參數去的CategoryStore組件(或可能不同的「IndividualCategoryStore」?),它返回特定於該類別的唯一的數據和處理更新/編輯該類別

我能夠通過添加新的方法(「getCategoryData得到了幾分這個工作的笨重版本「)傳遞到在」ManageCategory「組件的getInitialState方法中調用的CategoryStore,並傳遞給類別ryId參數。這會導致所有類別(來自CategoryStore的getDefaultData)的一個閃爍,然後是正確的單個類別列表(來自組件的getInitialState)。

我對React + Reflux背後的概念感到相當舒服,但在這一點上,我認爲這很可能是我誤解了一些根本性的東西。在這個特定的問題上工作了一個多星期,但沒有找到的示例/教程/文檔解決了將變量傳遞給數據存儲的具體問題。

操作:

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

CategoryStore:

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> 
    ); 
} 
}); 

ManageCategories組件:

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> 
    ); 
} 
}); 

提前感謝您的任何見解或幫助。

回答

2

在我終於在這裏發佈我的問題後,我想我可能已經知道我一直在誤入歧途。我在考慮將類別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> 
    ); 
} 
}); 

隨意讓我知道是否有更好的方法做到這一點,但現在這正是我所需要的。希望所有這些都會對其他人有所幫助。

+0

這個數據操作看起來不像組件內部。您可以將該責任卸載到商店,並讓您的組件使用給定的「catId」觸發一個操作。商店可以使用'catId'來檢索你的組件隨後將渲染的數據......然後你的組件代碼將不會與數據格式緊密結合。 –

+0

或者甚至可能只是在您的商店爲您獲取這些數據的幫手方法。好像你想在路由器和控制器視圖之間放一個緩衝區,這樣你就可以處理這個數據操作,因爲你必須爲應用中的每個頁面/控制器視圖做這樣的事情。 –

+0

但是,如果不同的組件以不同的方式期待數據與商店有什麼不同呢?我認爲這是一個非常糟糕的設計 –