【问题标题】:How to make Material UI List to open just one List Item?如何使 Material UI List 只打开一个 List Item?
【发布时间】:2017-08-31 08:45:58
【问题描述】:

我想在 React 中使用 Material-UI 中的列表,其中列表也有嵌套项。我有这样的代码:

<List>
    {this.state.categories.map(category => {
        return (
            <ListItem key={category.categoryID} 
                      primaryText={category.name}
                      nestedItems={[
                          category.subcategories.map(subcat => {
                              return (
                                  <ListItem key={subcat.subcatID}
                                            primaryText={subcat.name} />
                              )
                          })
                      ]} />
        )
    })}
</List>

虽然它在当前形式下可以工作,但它具有 List 的默认设置,这意味着我可以展开多个 ListItems 以查看它们的 nestedItems。但是,我想要手风琴的行为。用户一次只能展开一个ListItem 以查看其nestedItems。所以,如果一个已经展开并且用户点击展开另一个,已经展开的第一个应该关闭,而新按下的应该展开。知道如何使用 Material UI 中的 List 元素来实现这一点吗?

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    不要使用 List,而是使用 SelectableList 并以相同的方式定义 ListItems。要控制SelectableList 的打开/关闭行为,请对每个主列表项使用属性open

    查看此 DOC 页面的最后一个示例。

    代码:

    在状态变量中定义一个值:

    value: '';  //no list will be in open state initially
    

    用 SelectableList 定义 value 属性:

    <SelectableList value={this.state.value}>
        <ListItem
    
            value = {1}
            open = {this.state.value == 1? true: false}
            onClick = {() => this._click(1)}
    
            primaryText="Brendan Lim"
            primaryTogglesNestedList={true}
    
            nestedItems={[
                <ListItem
                    value='a'
                    primaryText="Grace Ng"
                />,
            ]}
        />
        <ListItem
    
            value = {2}
            open = {this.state.value == 2? true: false}
            onClick = {() => this._click(2)}
    
            primaryText="Brendan Lim"
            primaryTogglesNestedList={true}
            nestedItems={[
                <ListItem
                    value='b'
                    primaryText="Grace Ng"
                />,
            ]}
        />
    </SelectableList>
    
    
    _click(value){
       this.setState({value});
    }
    

    小鬼点数:

    1- 仅在主 ListItems 上定义 onClick,而不是在子项上。

    2- 在 _onClick 内部传递您使用主 ListItem 定义的相同值。

    3- 仅在主列表项而非子项上定义开放属性。

    4- 如果状态值与该列表项的值相同,则将条件放入 open 属性中,然后打开该列表并关闭所有其他列表。

    【讨论】:

    • 但这仍然可以扩展任意数量的项目。
    • 是的,默认情况下我们可以打开任何项目,但是列表项有一个属性open 我们可以使用它来控制打开和关闭行为,使用它并只打开一个项目一段时间后,它会起作用的。
    • @typos 检查更新的答案,在本地它工作正常,如果您有任何疑问,请告诉我:)
    【解决方案2】:

    一种方法是跟踪selectedItem,这样您就只渲染它的嵌套项。类似的东西:

    <List>
      {this.state.categories.map(category =>
        <ListItem
          key={category.categoryID}
          primaryText={category.name}
          nestedItems={
            category.categoryID === selectedItem ? [
              category.subcategories.map(subcat =>
                <ListItem key={subcat.subcatID} primaryText={subcat.name} />
              ),
            ] : []
          }
        />
      )}
    </List>
    

    【讨论】:

    • selectedItem 在哪里?我相信它不是List 的财产?
    • 您需要创建它。作为组件的 propstate 道具。因此,每次单击某个项目时,都会更新 selectedItem 值。
    • 谢谢。但是,我收到一条错误消息,提示我在 nestedItems 中提供布尔值。
    • 它在某种程度上有效,但没有达到我期望的效果。
    • 也许 SelectableList 适合您的需求。
    猜你喜欢
    • 2019-01-18
    • 1970-01-01
    • 2020-02-17
    • 2019-02-17
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多