javascript - 将 UI Fabric PeoplePicker 与 React 结合使用需要什么特别的东西吗?

标签 javascript reactjs office-addins office-ui-fabric office-ui-fabric-react

我正在尝试使用 UI Fabric 中的 Microsoft 控件 PeoplePicker 在我的应用程序中获得 Office 感觉。 我可以使用 Dropdown 和按钮等控件,但是当我想使用 PeoplePicker 时,即使我什么都不做,我也会在代码中遇到错误。

为了开始我的组件代码,我从https://developer.microsoft.com/en-us/fabric#/controls/web/peoplepicker复制粘贴普通人选择器,我收到两个错误(目前)。

  1. 第 48:66 行:解析错误:意外的标记,应为“,”,我的第 48 行是:
    return peopleList.filter(item => doesTextStartWith(item.text as string, filterText));
    指点item.text as string 。我猜这个错误来自于 as string 的使用在JS代码中。当我替换所有as string时至.toString() ,错误消失。
  2. 意外 token (26:79),我的第 26 行是:
    const [mostRecentlyUsed, setMostRecentlyUsed] = React.useState<IPersonaProps[]>(mru);
    指向[]之后IPersonaProps .

由于我从 Microsoft 获取代码,并且它无法在我的计算机上运行,​​所以我想我丢失了一些东西。我期望得到与他们网站上的示例相同的结果。

我的 Node 模块中有 office-ui-fabric-react

这是我的代码:

import * as React from 'react';
import { Checkbox } from 'office-ui-fabric-react/lib/Checkbox';
import { IPersonaProps } from 'office-ui-fabric-react/lib/Persona';
import { IBasePickerSuggestionsProps, NormalPeoplePicker, ValidationState } from 'office-ui-fabric-react/lib/Pickers';
import { people, mru } from '@uifabric/example-data';

const suggestionProps: IBasePickerSuggestionsProps = {
  suggestionsHeaderText: 'Suggested People',
  mostRecentlyUsedHeaderText: 'Suggested Contacts',
  noResultsFoundText: 'No results found',
  loadingText: 'Loading',
  showRemoveButtons: true,
  suggestionsAvailableAlertText: 'People Picker Suggestions available',
  suggestionsContainerAriaLabel: 'Suggested contacts'
};

const checkboxStyles = {
  root: {
marginTop: 10
  }
};

export const PeoplePickerNormalExample: React.FunctionComponent = () => {
  const [delayResults, setDelayResults] = React.useState(false);
  const [isPickerDisabled, setIsPickerDisabled] = React.useState(false);
  const [mostRecentlyUsed, setMostRecentlyUsed] = React.useState<IPersonaProps[]>(mru);
  const [peopleList, setPeopleList] = React.useState<IPersonaProps[]>(people);

  const picker = React.useRef(null);

  const onFilterChanged = (
filterText: string,
currentPersonas: IPersonaProps[],
limitResults?: number
  ): IPersonaProps[] | Promise<IPersonaProps[]> => {
if (filterText) {
  let filteredPersonas: IPersonaProps[] = filterPersonasByText(filterText);

  filteredPersonas = removeDuplicates(filteredPersonas, currentPersonas);
  filteredPersonas = limitResults ? filteredPersonas.slice(0, limitResults) : filteredPersonas;
  return filterPromise(filteredPersonas);
} else {
  return [];
}
  };

  const filterPersonasByText = (filterText: string): IPersonaProps[] => {
return peopleList.filter(item => doesTextStartWith(item.text as string, filterText));
  };

  const filterPromise = (personasToReturn: IPersonaProps[]): IPersonaProps[] | Promise<IPersonaProps[]> => {
if (delayResults) {
  return convertResultsToPromise(personasToReturn);
} else {
  return personasToReturn;
}
  };

  const returnMostRecentlyUsed = (currentPersonas: IPersonaProps[]): IPersonaProps[] | Promise<IPersonaProps[]> => {
setMostRecentlyUsed(removeDuplicates(mostRecentlyUsed, currentPersonas));
return filterPromise(mostRecentlyUsed);
  };

  const onRemoveSuggestion = (item: IPersonaProps): void => {
const indexPeopleList: number = peopleList.indexOf(item);
const indexMostRecentlyUsed: number = mostRecentlyUsed.indexOf(item);

if (indexPeopleList >= 0) {
  const newPeople: IPersonaProps[] = peopleList.slice(0, indexPeopleList).concat(peopleList.slice(indexPeopleList + 1));
  setPeopleList(newPeople);
}

if (indexMostRecentlyUsed >= 0) {
  const newSuggestedPeople: IPersonaProps[] = mostRecentlyUsed
    .slice(0, indexMostRecentlyUsed)
    .concat(mostRecentlyUsed.slice(indexMostRecentlyUsed + 1));
  setMostRecentlyUsed(newSuggestedPeople);
}
  };

  const onDisabledButtonClick = (): void => {
setIsPickerDisabled(!isPickerDisabled);
  };

  const onToggleDelayResultsChange = (): void => {
setDelayResults(!delayResults);
  };

  return (
<div>
  <NormalPeoplePicker
    onResolveSuggestions={onFilterChanged}
    onEmptyInputFocus={returnMostRecentlyUsed}
    getTextFromItem={getTextFromItem}
    pickerSuggestionsProps={suggestionProps}
    className={'ms-PeoplePicker'}
    key={'normal'}
    onRemoveSuggestion={onRemoveSuggestion}
    onValidateInput={validateInput}
    removeButtonAriaLabel={'Remove'}
    inputProps={{
      onBlur: (ev: React.FocusEvent<HTMLInputElement>) => console.log('onBlur called'),
      onFocus: (ev: React.FocusEvent<HTMLInputElement>) => console.log('onFocus called'),
      'aria-label': 'People Picker'
    }}
    componentRef={picker}
    onInputChange={onInputChange}
    resolveDelay={300}
    disabled={isPickerDisabled}
  />
  <Checkbox label="Disable People Picker" checked={isPickerDisabled} onChange={onDisabledButtonClick} styles={checkboxStyles} />
  <Checkbox
    label="Delay Suggestion Results"
    defaultChecked={delayResults}
    onChange={onToggleDelayResultsChange}
    styles={checkboxStyles} />
</div>
  );
};

function doesTextStartWith(text: string, filterText: string): boolean {
  return text.toLowerCase().indexOf(filterText.toLowerCase()) === 0;
}

function removeDuplicates(personas: IPersonaProps[], possibleDupes: IPersonaProps[]) {
  return personas.filter(persona => !listContainsPersona(persona, possibleDupes));
}

function listContainsPersona(persona: IPersonaProps, personas: IPersonaProps[]) {
  if (!personas || !personas.length || personas.length === 0) {
return false;
  }
  return personas.filter(item => item.text === persona.text).length > 0;
}

function convertResultsToPromise(results: IPersonaProps[]): Promise<IPersonaProps[]> {
  return new Promise<IPersonaProps[]>((resolve, reject) => setTimeout(() => resolve(results), 2000));
}

function getTextFromItem(persona: IPersonaProps): string {
  return persona.text as string;
}

function validateInput(input: string): ValidationState {
  if (input.indexOf('@') !== -1) {
return ValidationState.valid;
  } else if (input.length > 1) {
return ValidationState.warning;
  } else {
return ValidationState.invalid;
  }
}

/**
 * Takes in the picker input and modifies it in whichever way
 * the caller wants, i.e. parsing entries copied from Outlook (sample
 * input: "Aaron Reid <aaron>").
 *
 * @param input The text entered into the picker.
 */
function onInputChange(input: string): string {
  const outlookRegEx = /<.*>/g;
  const emailAddress = outlookRegEx.exec(input);

  if (emailAddress && emailAddress[0]) {
return emailAddress[0].substring(1, emailAddress[0].length - 1);
  }

  return input;
}

我在我的应用程序中像这样使用它。我已经把<...>保持代码简短。一切都在这个部分进行。

import React from 'react';
import { Fabric } from 'office-ui-fabric-react/lib/Fabric'
import PeoplePickerNormalExample from "./components/MyCustom_Picker.js"

class App extends React.Component {
  render() {
    return ( 
      <Fabric className = "App" >
        <PeoplePickerNormalExample / >
        <...>
      </Fabric>
    );
  }
}

export default App;

最佳答案

我认为您的应用不是 Typescript (TS) 格式的。您要复制的 Office UI 示例位于 TS 中。要将示例转换回普通 JS,请删除类型(例如 : string: number: IPersonaProps[])。

查看此链接:https://www.typescriptlang.org/play/ 。将示例代码粘贴到其中尝试将其转换为 JS。

关于javascript - 将 UI Fabric PeoplePicker 与 React 结合使用需要什么特别的东西吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60764481/

相关文章:

outlook-addin - Outlook 加载项中的 RoamingSettings 似乎无法正常工作

c# - 使用 WiX 安装 VSTO Office 插件

javascript - 菜单打开时移动 View 问题?

javascript - 圆边的边框塌陷?

javascript - 如何在一个 onClick/onPress 方法上传递 2 个 props?

javascript - React Navigation 5 - 在导航到另一个选项卡中的另一个堆栈之前重置堆栈(类似于 popToTop())

outlook-addin - Office.context.ui.displayDialogAsync 抛出 5001 内部错误

javascript - 无法让 JQuery 回调函数工作

javascript - 带有backbone.js的模板

javascript - 禁用输入字段填充 1 个字符时自动跳转到下一个输入字段