Microsoft Graph 工具包组件消除歧义

Microsoft Graph 工具包是使用 Web 组件生成的。 在浏览器中注册时,Web 组件使用其标记名称作为唯一键。 调用 时 CustomElementRegistry.define(),任何使用以前注册的标记名称注册组件的尝试都会导致错误。 在可以将多个自定义应用程序加载到单个页面中的方案中,这给 Microsoft Graph 工具包造成了问题,尤其是在使用 SharePoint 框架 开发解决方案时。

mgt-spfx 包有助于缓解此挑战。 通过使用 mgt-spfx,可以在租户上部署的所有 SPFx 解决方案中集中注册 Microsoft Graph 工具包 Web 组件。 通过从中心位置重用工具包组件,可将不同解决方案中的 Web 部件加载到单个页面中,而不会引发错误。 使用 mgt-spfx时,SharePoint 租户中所有基于 Microsoft Graph 工具包的 Web 部件都使用相同的工具包版本。

消除歧义功能使你能够使用最新版本的 Microsoft Graph 工具包生成 Web 部件,并将其与使用 v2.x 的 Web 部件一起加载到页面上。 通过使用此功能,可以指定要添加到其应用程序中所有工具包 Web 组件的标记名称的唯一字符串。 使用消除歧义时,所提供的值将作为标记名称的第二段插入,因此在使用 customElementHelper.withDisambiguation('foo')<mgt-login> 标记时,使用 <mgt-foo-login>引用 。

注册调用 CustomElementRegistry.define()的自定义元素时,输入的名称必须是 有效的自定义元素名称。 为了获得更好的开发人员体验, withDisambiguation 该方法会自动将提供的值转换为小写,如果提供的值包含任何非小写字符,则会在开发人员控制台中发出警告。 此帮助程序方法不会完全净化输入,并且基础 define 方法调用可能仍然失败,并出现类似 的错误 DOMException: Failed to execute 'define' on 'CustomElementRegistry': "mgt-MyName-flyout" is not a valid custom element name

使用 React SharePoint 框架 Web 部件

使用 React 生成SharePoint 框架 Web 部件时,必须在配置消除歧义设置后异步加载从@microsoft/mgt-react库导入的任何组件。 帮助 lazyLoadComponent 程序函数的存在有助于使用 React.lazyReact.Suspense 延迟从顶级 Web 部件加载这些组件。 包 lazyLoadComponent@microsft/mgt-spfx-utils 提供了 函数。 由于仅在呈现 Web 组件时使用消除歧义值,因此在React代码中引用给定组件的方式没有变化。

以下示例演示了一个最小 Web 部件,该部件演示如何在基于React的 web 部件中使用具有消除歧义的 Microsoft Graph 工具包SharePoint 框架。 有关更完整的示例,请参阅 React SharePoint Web 部件示例

// [...] trimmed for brevity
import { Providers } from '@microsoft/mgt-element/dist/es6/providers/Providers';
import { customElementHelper } from '@microsoft/mgt-element/dist/es6/components/customElementHelper';
import { SharePointProvider } from '@microsoft/mgt-sharepoint-provider/dist/es6/SharePointProvider';
import { lazyLoadComponent } from '@microsoft/mgt-spfx-utils';

// Async import of component that imports the React Components
const MgtDemo = React.lazy(() => import('./components/MgtDemo'));

export interface IMgtDemoWebPartProps {
  description: string;
}
// set the disambiguation before initializing any webpart
// Use the solution name to ensure unique tag names
customElementHelper.withDisambiguation('spfx-solution-name');

export default class MgtDemoWebPart extends BaseClientSideWebPart<IMgtDemoWebPartProps> {
  // set the global provider
  protected async onInit() {
    if (!Providers.globalProvider) {
      Providers.globalProvider = new SharePointProvider(this.context);
    }
  }

  public render(): void {
    const element = lazyLoadComponent(MgtDemo, { description: this.properties.description });

    ReactDom.render(element, this.domElement);
  }

  // [...] trimmed for brevity
}

注意: 如果顶级 Web 部件从 @microsoft/mgt-react@microsoft/mgt-components导入任何代码,则消除歧义将不起作用。

然后,基础组件可以像往常一样使用包中的 @microsoft/mgt-react 工具包组件。 由于前面的设置步骤,工具包React组件将使用消除歧义的标记名称呈现 HTML:

import { Person } from '@microsoft/mgt-react';

// [...] trimmed for brevity

export default class MgtReact extends React.Component<IMgtReactProps, {}> {
  public render(): React.ReactElement<IMgtReactProps> {
    return (
      <div className={ styles.mgtReact }>
        <Person personQuery="me" />
      </div>
    );
  }
}

React中的使用情况

若要在React应用程序中使用消除歧义,请在加载和呈现根组件之前调用 customElementHelper.withDisambiguation() 。 为了帮助在此方案中进行延迟加载,React React版本 16.6 及版本或更高版本中提供了 lazy 函数和Suspense组件。

import React, { lazy, Suspense } from 'react';
import ReactDOM from 'react-dom';
import { customElementHelper, Providers } from '@microsoft/mgt-element';
import { Msal2Provider } from "@microsoft/mgt-msal2-provider";

customElementHelper.withDisambiguation('contoso');

Providers.globalProvider = new Msal2Provider({ clientId: 'clientId' });

const App = lazy(() => import('./App'));
ReactDOM.render(<Suspense fallback='...'><App /></Suspense>, document.getElementById('root'));

标准 HTML 和 JavaScript 中的用法

若要在使用标准 HTML 和 JavaScript 时使用消除歧义功能,请在导入@microsoft/mgt-components模块之前调用 customElementHelper.withDisambiguation()

<script type="module">
  import { Providers, customElementHelper } from '@microsoft/mgt-element';
  import { Msal2Provider } from "@microsoft/mgt-msal2-provider";
  // configure disambiguation
  customElementHelper.withDisambiguation('contoso');

  // initialize the auth provider globally
  Providers.globalProvider = new Msal2Provider({clientId: 'clientId'});

  // import the components using dynamic import to avoid hoisting
  import('@microsoft/mgt-components');
</script>

<mgt-contoso-login></mgt-contoso-login>
<mgt-contoso-person person-query="Bill Gates" person-card="hover"></mgt-contoso-person>
<mgt-contoso-agenda group-by-day></mgt-contoso-agenda>

重要

importmgt-components 必须使用动态导入来确保在导入组件之前应用消除歧义。 如果使用静态导入,则会 提升 该导入,并在应用消除歧义之前进行导入。

动态导入 (延迟加载)

使用动态导入,可以异步加载依赖项。 此模式允许仅在需要时加载依赖项。 例如,你可能希望仅在用户单击按钮时加载组件。 这是减少应用程序初始加载时间的好方法。 在消除歧义的上下文中,你需要使用此技术,因为组件在导入时会自行注册到浏览器中。

重要: 如果在应用消除歧义之前导入组件,则不会应用消除歧义,并且使用消除歧义的标记名称将不起作用。

使用 import 语句时,import 语句将 提升 并在代码块中的任何其他代码之前运行。 若要使用动态导入,必须使用 import() 函数。 函数 import() 返回解析为模块的 promise。 还可以使用 then 方法在加载模块后运行代码, catch 并在必要时使用 方法处理任何错误。

使用动态导入的示例

// static import via a statement
import { Providers, customElementHelper } from '@microsoft/mgt-element';
import { Msal2Provider } from "@microsoft/mgt-msal2-provider";

customElementHelper.withDisambiguation('contoso');
Providers.globalProvider = new Msal2Provider({clientId: 'clientId'});

// dynamic import via a function
import('@microsoft/mgt-components').then(() => {
  // code to execute after the module is loaded
  document.body.innerHTML = '<mgt-contoso-login></mgt-contoso-login>';
}).catch((e) => {
  // handle any errors
});

使用静态导入的示例

// static import via a statement
import { Providers } from '@microsoft/mgt-element';
import { Msal2Provider } from "@microsoft/mgt-msal2-provider";
import '@microsoft/mgt-components';

Providers.globalProvider = new Msal2Provider({clientId: 'clientId'});

document.body.innerHTML = '<mgt-login></mgt-login>';

注意: 不能对静态导入使用消除歧义。