css - ReactJS+MaterialUI v1 自动嵌套列表填充

标签 css reactjs typescript material-ui nested-lists

我有嵌套列表,但我不知道有多少(递归函数)。如何让他们获得自动填充?

我得到的结果是这样的

enter image description here :

我想得到这个结果:

enter image description here

如果我添加嵌套样式,它们对于所有嵌套列表都是相同的。我需要为每个下一个级别增加填充。

你能帮忙吗? (欢迎大家评论!)

代码:

import React from 'react';
import {isNullOrUndefined} from "util";
import {TagNode} from "../interfaces/TagTree";
import HistoryDataUtility from "../../utilities/historyDataUtility";
import TreeUtility from "../../utilities/treeUtility";

import { createStyles } from '@material-ui/core/styles';
import { withStyles } from '@material-ui/core/styles';
import Checkbox from '@material-ui/core/Checkbox';
import Collapse from '@material-ui/core/Collapse';
import Icon from '@material-ui/core/Icon';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
import ListItemText from '@material-ui/core/ListItemText';


export interface TreeRendererProps {
    itemList: TagNode[],
    selectedTags: string[],
    expandedFolders: string[],
    onFolderToggle: any,
    onTagToggle: any,
    onSelectedFolderChange?: any,
    selectedFolder?: string,
    classes: {
        root: string;
        nested: string;
    }
}

const styles = createStyles({
    root: {
        width: '100%',
    },
    nested: {
        paddingLeft: 16
    }
});

const TreeRenderer: React.StatelessComponent<TreeRendererProps> = (props) => {


    const buildListItems = (item: TagNode,
                                                    selectedTags: string[],
                                                    onFolderToggle: any,
                                                    onTagToggle: any,
                                                    source: string) => {
        let key = HistoryDataUtility.combineTag(source, item.objId);
        let isExpanded = props.expandedFolders.indexOf(key) != -1;
        let isSelected: boolean = props.selectedFolder === key ? true : false;

        let children1: any, children2: any;

        if(!TreeUtility.isTagItem(item)) {
            children1 = item.children.filter(filterGroups).sort(sortOnTitle).map((child) => {
                                    return buildListItems(child,
                                        selectedTags,
                                        onFolderToggle,
                                        onTagToggle,
                                        source);
                                }) || null;
            children2 = item.children.filter(filterTags).sort(sortOnTitle).map((child) => {
                                    return buildListItems(child,
                                        selectedTags,
                                        onFolderToggle,
                                        onTagToggle,
                                        source);
                                }) || null;
        }

        let collapseItem: any;
        if(isExpanded && !isNullOrUndefined(item.children)) {
            collapseItem =
                <Collapse component="li" in={true} timeout="auto" unmountOnExit>
                    <List disablePadding>
                        {children1}
                        {children2}
                    </List>
                </Collapse>
        }

        let key2 = "list" + Math.random().toString(36).substr(2, 9);

        return (
            !TreeUtility.isTagItem(item)
            ?
                <div key={key2}>
                    <ListItem
                        button key={key}
                        className={props.classes.nested + " with-children"}
                        onClick={onFolderToggle.bind(this, key)}
                        >
                        <ListItemIcon>
                            {isExpanded ? <Icon>remove</Icon> : <Icon>add</Icon>}
                        </ListItemIcon>
                        <ListItemText primary={item.title} />
                        <ListItemSecondaryAction>
                            <Checkbox checked={isSelected} color="primary" onChange={props.onSelectedFolderChange} value={key} />
                        </ListItemSecondaryAction>
                    </ListItem>
                    {collapseItem}
                </div>

            :

                <ListItem
                    button
                    className={props.classes.nested + " no-children" + ((selectedTags.indexOf(key) != -1 || selectedTags.indexOf(item.objId) != -1)    ? " tagitem-activated" : "")}
                    key={key}
                    onClick={onTagToggle.bind(this, key)}
                    >
                    <ListItemIcon><Icon className="status">fiber_manual_record</Icon></ListItemIcon>
                    <ListItemText primary={item.title} />
                </ListItem>
        );
    }

    const filterGroups = (item: TagNode): boolean => {
        return !TreeUtility.isTagItem(item);
    }

    const filterTags = (item: TagNode): boolean => {
        return TreeUtility.isTagItem(item);
    }

    const sortOnTitle = (a: TagNode, b: TagNode) => {
        var nameA = a.title.toUpperCase(); // ignore upper and lowercase
        var nameB = b.title.toUpperCase(); // ignore upper and lowercase
        if (nameA < nameB) {
            return -1;
        }
        if (nameA > nameB) {
            return 1;
        }
        // names must be equal
        return 0;
    }

    const buildList = (items: TagNode[],
                                         selectedTags: string[],
                                         onFolderToggle: any,
                                         onTagToggle: any) => {

        let children1: any, children2: any;

        children1 = items.filter(filterGroups).sort(sortOnTitle).map((item: TagNode) => {
                            let source = item.objId; //Use the top level group nodes id as source
                            return buildListItems(
                                item,
                                selectedTags,
                                onFolderToggle,
                                onTagToggle, source);
                        }) || null;

        children2 = items.filter(filterTags).sort(sortOnTitle).map((item: TagNode) => {
                            return buildListItems(
                                item,
                                selectedTags,
                                onFolderToggle,
                                onTagToggle, null);
                        }) || null;

        return (
             <List>
                {children1}
                {children2}
            </List>
        )
    }

    let tree;

    if (props.itemList.length > 0) {
        if (props.itemList[0].children != undefined) {
            tree = buildList(
                props.itemList[0].children,
                props.selectedTags,
                props.onFolderToggle,
                props.onTagToggle);
        } else {
            tree = <div>{props.itemList[0].name + ' : ' + props.itemList[0].title}</div>
        }
    } else {
        tree = <div><h2 className="small">Model not found.</h2></div>;
    }

    return (<div>{tree}</div>);
}

export default withStyles(styles, { withTheme: true })(TreeRenderer);

最佳答案

实际上,解决方案非常简单。只需更改此行:

<Collapse component="li" in={true} timeout="auto" unmountOnExit>

为此:

<Collapse component="li" in={true} timeout="auto" unmountOnExit style={{paddingLeft: '16px'}}>

关于css - ReactJS+MaterialUI v1 自动嵌套列表填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51498023/

相关文章:

javascript - 如何在对象中嵌套对象?

javascript - 简单的 Ajax 请求,在 React.js 中循环数据

Angular - 动态加载图像

css - 相同的图像,两种尺寸

reactjs - 如何使用 Webpack/SplitChunks 插件按目录动态拆分?

javascript - 如何在 Angular 中构建延迟加载侧边栏?

typescript - 如何在保持默认行为的同时扩展 tsconfig 中的类型

javascript - 我正在尝试从存储在数据库中的 pdf 中检索,但是它返回的是路径而不是文件本身

html - 调整页面大小后下拉菜单不起作用

css - 哪个属性用于更改元素的字体?