reactjs基于配置对象的条件组件方法

时间:2014-10-22 19:12:44

标签: function coffeescript reactjs

我正在设置一个可排序的可过滤表,我正在尝试制作它,以便我可以在组件上定义对象以构建所有必需的功能。

我想接受这个,

RailsTable = React.createClass
  mixins: [
    Backbone.React.Component.mixin
  ]

  setSearchTermFilter: (e)->
    search_term = e.target.value
    @setState(search_term: search_term)

  setGroupNumberFilter: (e)->
    rail_group = parseInt(e.target.value)
    @setState(rail_group: rail_group)

  setSystemNameFilter: (e)->
    system_name = e.target.value
    @setState(system_name: system_name)

  filteredResults: ->
    filteredResults = @getCollection()
    filteredResults = filteredResults.bySearchTerm(@state.search_term)
    filteredResults = filteredResults.byRailGroup(@state.rail_group)
    filteredResults = filteredResults.bySystemName(@state.system_name)

    filteredResults.sortDirection = @state.sortDirection
    filteredResults.sortBy(@state.sortAttribute)
    filteredResults



  render: ->
    blah

并将其纳入其中,

RailsTable = React.createClass
  mixins: [
    Backbone.React.Component.mixin
    Evue.Mixins.FilterMixin
  ]

  filterTypes:
    'search_term'  : ''
    'system_name'  : ''
    'rail_group'   : 0

  render: ->
    blah

我认为这很好,但混乱中出现了麻烦。我需要遍历filterTypes对象并基于此创建函数。所以,如果我有search_term,那么我需要一个setSearchTermFilter函数,但每个表都有各种属性,所以我需要根据我输入的内容创建它们。

这是我想要的想法,但不起作用,

Evue.Mixins.FilterMixin =

  getInitialState: ->
    @searchTypes

  @filterTypes.each (filterObject)->
    setFilterObject: (newFilterObject)->
      @setState(filterObject: newFilterObject)

我甚至不知道这是否可行而且我真的认为我只是接近这个错误。

1 个答案:

答案 0 :(得分:1)

让我们瞄准这个设计。 mixin是专门为组件创建的,它允许它更具动态性(包括具有动态功能)。

RailsTable = React.createClass
  mixins: [
    Backbone.React.Component.mixin
    Evue.Mixins.makeFilterMixin {
      'search_term'  : ''
      'system_name'  : ''
      'rail_group'   : 0
    }
  ]
  render: ->
    blah

首先我们必须创建这个函数,并在初始的snake_case和PascalCase中获取过滤器的名称。

Evue.Mixins.makeFilterMixin = (filters) ->
  mixin = {}
  filterNames = Object.keys filters
  filterNamesToPascal = {}

  filterNames.forEach (name) ->
    filterNamesToPascal[name] = pascalCase(name)

初始状态函数很简单。

  mixin.getInitialState = ->
    state = {}
    for name in filterNames
      state[name] = filters[name]
    state

这是我们使用filterNamesToPascal的第一个地方。对于search_term过滤器,filterFnName类似于"bySearchTerm"。然后我们将状态值传递给它,并继续循环过滤。

  mixin.filteredResults = ->
    filteredResults = @getCollection()
    for filter in filterNames
      filterFnName = "by" + filterNamesToPascal[filter]
      filteredResults = filteredResults[filterFnName](this.state[filter])

    filteredResults.sortDirection = @state.sortDirection
    filteredResults.sortBy(@state.sortAttribute)
    filteredResults

这是我们需要一个返回mixin的函数的主要原因。要动态创建setSearchTermFilter等函数,我们需要直接在mixin上设置它们。我们使用默认值的构造函数将其转换回正确的类型。这适用于String和Number等原始构造函数。您放弃了为数字类型强制执行整数的功能。要做到这一点,你必须有一个全功能的架构。

  filterNames.forEach (name) ->
    constructor = filters[name]?.constructor || String
    mixin["set" + filterNamesToPascal[name] + "Filter"] = (e) ->
      update = {}
      update[name] = constructor e.target.value
      @setState update
  mixin    

最后,一个简单的实用函数将snake_case用于PascalCase。

pascalCase = (s) ->
  words = s.split("_").map (x) ->
    x[0].toUpperCase() + x.slice(1)
  words.join("")