【问题标题】:Context Menu not reflecting check/uncheck on click上下文菜单不反映单击时选中/取消选中
【发布时间】:2020-09-28 12:22:39
【问题描述】:

我有一个点击按钮的上下文菜单。最初检查的项目有 3 个。单击每个项目时,我正在切换检查。上下文菜单打开时,选中/取消选中不会反映。这曾经可以更早地工作,但在最新的 react 版本中它看起来已经被破坏了。

sn-p在这里

import { initializeIcons } from '@uifabric/icons';
import { DefaultButton, IContextualMenuItem, IContextualMenuProps, IContextualMenuStyles } from 'office-ui-fabric-react';
import React from 'react';
initializeIcons();

//Without this style defined, check/uncheck will not reflect in UI.
const cmStyles:Partial<IContextualMenuStyles> = {
    title:{},
    header:{},
    list:{
    },
    root:{
    },
    subComponentStyles:{
        callout:{
            root:{
            }
        },
        menuItem:{}
    },
    container:{
    }
}

const keys: string[] = [
    'Item1',
    'Item2',
    'Item3'
];

interface IState {
    updateUI: boolean;
}

export default class ContextMenuCheck extends React.Component<{}, IState>{
    state:IState = {
        updateUI: false
    }

    constructor(props:any){
        super(props);
    }

    onTogglePlanType = (ev?: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>, item?: IContextualMenuItem):void => {
        ev && ev.preventDefault();//This will not close the menu
        item.checked = !item.checked;
        this.setState({updateUI:true});
    };

    menuItems: IContextualMenuItem[] = [
        {
          key: keys[0],
          text: keys[0],
          canCheck: true,
          checked: true,
          onClick: this.onTogglePlanType
        },
        {
          key: keys[1],
          text: keys[1],
          canCheck: true,
          checked: true,
          onClick: this.onTogglePlanType
        },
        {
          key: keys[2],
          text: keys[2],
          canCheck: true,
          checked: true,
          onClick: this.onTogglePlanType
        }
    ];

    menuProps: IContextualMenuProps = {
        items:this.menuItems,
        styles: cmStyles
    };

    componentDidMount() {
    }

    render() {
        return (
        <DefaultButton text="Click Me"  menuProps={this.menuProps}/>
        );
    }
}

ReactDOM.render(
  <ContextMenuCheck />, 
  document.getElementById("content")
);

【问题讨论】:

    标签: office-ui-fabric react-tsx office-ui-fabric-react fluent-ui


    【解决方案1】:

    我整理了一个working example here

    您的样品很接近,只是缺少一些部分:

    • 由于 menuItems 是用硬编码为 true 的 checked 定义的,因此上下文菜单从不呈现那些没有选中标记的菜单。
    • 在我的示例中,我将菜单项选中状态置于整体状态,以便onTogglePlanType 能够为每个单独的菜单项设置选中(或未选中)。
    • 最后,menuItems 必须在每次渲染时重新构建,以便在构建菜单时能够将 checked 考虑在内。

    我将IState 更改为只保留选中的值:

    type itemChecked = { [key: string]: boolean };
    
    interface IState {
        checkedMenuItems: itemChecked;  
    }
    

    然后我将回调更改为显式设置每个菜单项的值:

    onTogglePlanType = (ev?: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>, item?: IContextualMenuItem):void => {
            ev && ev.preventDefault();
            // Use ... syntax to make a copy of the object
            const itemChecked = { ...this.state.itemChecked }; 
            itemChecked[item.key] = !itemChecked[item.key];
    
            this.setState({ itemChecked: itemChecked });
        };
    

    然后,通过将menuItems 的定义移动到render() 函数中,它按预期工作。

    【讨论】:

    • 您好 JD Huntington,感谢您的回复。您已经提到如果项目是完全相同的数组,则不会发生更新。这是最近改变的东西吗?我有一个 vscode 示例,其中确切的代码可以工作。即检查/取消检查确实会在不重新创建数组的情况下更新。不同之处在于几个月前的 package.json。谢谢
    • 恐怕我不知道这个特殊功能的历史。它最近可能已更改。也就是说,让 props 反映组件的外观是确保此类菜单正常工作且面向未来的最佳方式。以前版本的 Fabric 中存在一些允许 React 反模式工作的错误,但随着时间的推移,这些错误正在被清除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多