如果你在一个页面上有很多这样的话,Popover不起作用。如何管理它们?

时间:2016-04-30 10:31:37

标签: reactjs material-ui

这里的示例http://www.material-ui.com/#/components/popover仅对页面上的一个Popover元素有效。如果按照他们的示例,一个页面上不可能有多个Popover。因为Popovers开始互相干扰。

例如。这是单个popover的标记。并且假设您在一个页面中有十个这样的内容:

<div onClick={this.openPopover}>Open Popover</div>
<Popover
    open={this.state.open}
    anchorEl={this.state.anchorEl}
    anchorOrigin={{horizontal: 'left', vertical: 'bottom'}}
    targetOrigin={{horizontal: 'left', vertical: 'top'}}
    onRequestClose={this.closePopover}
    animated={true}
    >
    <div style={{padding: '20px'}}>
        <p>Hello World</p>
    </div>
</Popover>

根据material-ui.com示例,这是他们的React处理程序。有了这个,如果我触发一个弹出窗口,它们都会被打开。因为this.state.open对于每个popover都很常见:

getInitialState() {
    return {
        open: false,
    };
},

    openPopover(event) {
        this.setState({
            open: true,
            anchorEl: event.currentTarget,
        });
    },
    closePopover(reason: string) {
        this.setState({
             open: false,
        });
    },

我希望只有这两个处理程序 - openPopoverclosePopover。我不想为我的10个popovers创建20个单独的处理程序。

由于closePopover函数的奇怪签名(由于某种原因,他们希望使用字符串而不是eventanchorElement),因此无法将其传递给在ES6允许的情况下即时确定属性,例如:

getInitialState() {
    return {
        popover1: false,
    };
},

    // e.g. getAttribute('data-name') == 'popover1'
    // <div onClick={this.openPopover} data-name="popover1">Open Popover</div>

    openPopover(event) {
        this.setState({
            [event.currentTarget.getAttribute('data-name')]: true,
            anchorEl: event.currentTarget,
        });
    },

    // and here instead of useless "reason: string", an event or anchorElement would do the trick
    closePopover(reason: string) {
        this.setState({
             [event.currentTarget.getAttribute('data-name')]: false,
        });
    },

在一个页面中有多个弹出窗口的material-ui.com最佳做法是什么?希望答案不是为页面上的每个弹出框创建一个单独的React Popover类。也希望不要为每个popover创建一个单独的处理函数。

2 个答案:

答案 0 :(得分:2)

处理多个类似材料-ui组件的正确方法是使用回调函数绑定名称。

例如,你必须处理两个popover: 为每个弹出窗口定义状态标识符,如下面的构造函数:

this.state = {
    first : false,
    second: false,
    };

然后您可以使用以下命令调用单个弹出操作:

onTouchTap={this.handleTouchTap.bind(this, 'first')} 

onTouchTap={this.handleTouchTap.bind(this, 'second')} 

最后在handleTouchTap函数中,您可以定义:

handleTouchTap(name, event, index, value) {


    event.preventDefault();
    var change = {};
    change[name] = true;

    this.setState(change)

  };

这不需要创建多个处理程序。您只需要绑定名称即可识别它们。

答案 1 :(得分:0)

备选方案:

  1. 创建20个处理程序(我知道你不想这样做)

  2. 根据它们附加的内容,您可以创建自己的组件来封装字段/标题/ etc和popover。如果您的所有字段都属于同一类型,则应该很容易。如果你有5个,那么你需要创建5个不同的组件。

  3. 在您的锚元素中嵌入一个标识符,然后使用大开关或if-elseif链从处理程序中键入。

  4. 编写一个handlerCreator函数,该函数返回一个闭包,该函数在handlerCreate函数返回函数闭包时封装标识符。