For AI agents: the complete documentation index is available at /next/zh/llms.txt, the full documentation bundle is available at /next/zh/llms-full.txt, and this page is available as Markdown at /next/zh/guide/use-data-from-host-platform.md.
Lynx
  • 简体中文
  • 使用宿主平台数据

    Lynx 允许宿主平台在页面加载时提供一份初始数据,并且在之后随时对这些数据进行更新。 这份初始数据被称为 initData

    提供和更新数据

    前置步骤

    你需要完成接入现有应用中的指引,以确保你的应用已经集成了 Lynx,并对 Lynx 的 Native API 有基本的了解。

    在使用 LynxView.loadTemplate() 加载一个 Bundle 的时候,你有机会传入一些数据:

    LynxLoadMeta* meta = [LynxLoadMeta init];
    // meta.url = @"";
    // meta.binaryData = nil;
    // meta.templateBundle = nil;
    meta.initialData = __YOUR_DATA__;
    // meta.loadOption = LynxLoadOptionDumpElement | LynxLoadOptionRecycleTemplateBundle;
    [lynxView loadTemplate:meta];
    LynxLoadMeta.Builder builder = new LynxLoadMeta.Builder();
    // builder.setUrl();
    // builder.setBinaryData();
    // builder.setTemplateBundle();
    builder.setInitialData(__YOUR_DATA__);
    // builder.addLoadOption();
    LynxLoadMeta meta = builder.build();
    lynxView.loadTemplate(meta);
    @Entry
    @Component
    struct Index {
      private metaData: MetaData = new MetaData(new TemplateData(__YOUR_DATA__));
    
      build() {
        Column() {
          LynxView({
            // url: this.url,
            // buffer: this.buffer,
            metadata: this.metaData,
          }).width('100%').height('100%');
        }
        .size({ width: '100%', height: '100%' })
      }
    }

    你可以在后续需要的时机通过 LynxView.updateData() (或 HarmonyOS 平台的 LynxContext.updateData()) 来更新这些数据:

    LynxUpdateMeta* meta = [LynxUpdateMeta init];
    meta.data = __YOUR_DATA__;
    [lynxView updateData:meta];
    LynxUpdateMeta.Builder builder = new LynxUpdateMeta.Builder();
    builder.setUpdatedData(__YOUR_DATA__);
    LynxUpdateMeta meta = builder.build();
    lynxView.updateMetaData(meta);
    @Entry
    @Component
    struct Index {
      private metaData: MetaData = new MetaData(new TemplateData(__YOUR_DATA__));
      private context?: LynxContext;
    
      build() {
        Column() {
          LynxView({
            // url: this.url,
            // buffer: this.buffer,
            metadata: this.metaData,
            onCreate: (context: LynxContext) => {
              this.context = context;
              this.context.updateMetaData(new MetaData(new TemplateData(__YOUR_DATA__)));
            }
          }).width('100%').height('100%');
        }
        .size({ width: '100%', height: '100%' })
      }
    }

    你在加载时传入的数据和后续更新时传入的数据都可以在前端使用,下面是如何在前端使用这些数据。

    使用数据

    前端可以通过 useInitData() 来获取 initData。 在宿主平台更新数据时,这些组件会自动重新渲染。

    src/App.jsx
    import { useInitData } from '@lynx-js/react';
    
    function App() {
      const initData = useInitData();
      return (
        <view>
          <text>{initData.greeting}</text>
        </view>
      );
    }

    如果你使用传统的类组件,那么可以使用 InitDataConsumer

    import { Component, InitDataProvider, InitDataConsumer } from '@lynx-js/react';
    
    class C extends Component {
      render() {
        return (
          <InitDataConsumer>
            {(initData) => (
              <view>
                <text>{initData.greeting}</text>
              </view>
            )}
          </InitDataConsumer>
        );
      }
    }

    注意 InitDataConsumer 必须作为 InitDataProvider 的子节点使用。

    <InitDataProvider>
      <view>
        <C />
      </view>
    </InitDataProvider>

    使用数据前进行预处理

    虽然 useInitData() 会从宿主平台为你提供 initData,但它可能不是你期望的格式。

    想象一下,你有以下混乱的 initData

    • 在 Android 或 HarmonyOS 上:

      {
        "pageTitle": "Hello Lynx"
      }
    • 但是,在 iOS 上:

      {
        "page_title": "Hello Lynx"
      }

    如果你想要兼容这些平台,你的代码可能会变得不那么干净:

    import { useInitData } from '@lynx-js/react';
    
    export function App() {
      const initData = useInitData();
      return (
        <view>
          <text>{initData.pageTitle || initData.page_title}</text>
        </view>
      );
    }

    上述场景只是示例,但 Lynx 确实提供了一种在使用之前处理 initData 的方法,它被称为 dataProcessor

    使用默认 dataProcessor

    如果你(或宿主平台开发人员)没有指定 processorName,Lynx 将使用 defaultDataProcessor 来处理 initData

    Info

    前往 lynx.registerDataProcessors 查看更多示例。

    src/index.tsx
    import { root } from '@lynx-js/react';
    import { App } from './App.js';
    
    lynx.registerDataProcessors({
      defaultDataProcessor: function (rawInitData) {
        const { pageTitle, page_title, ...rest } = rawInitData;
        return {
          ...rest,
          pageTitle: pageTitle || page_title,
        };
      },
    });
    root.render(<App />);
    
    if (import.meta.webpackHot) {
      import.meta.webpackHot.accept();
    }

    然后,在你的组件中,你可以直接使用 initData

    src/App.jsx
    import { useInitData } from '@lynx-js/react';
    
    export function App() {
      const initData = useInitData();
      return (
        <view>
          <text>{initData.pageTitle}</text>
        </view>
      );
    }

    使用命名的 dataProcessor

    你(或宿主平台开发人员)还可以在调用 LynxView.updateData() (或 HarmonyOS 平台的 LynxContext.updateData()) 时指定 processorName

    LynxUpdateMeta *meta = [[LynxUpdateMeta alloc] init];
    
    [lynxView updateData:meta];
    LynxUpdateMeta meta = new LynxUpdateMeta();
    
    lynxView.updateMetaData(meta);
    @Entry
    @Component
    struct Index {
      private metaData: MetaData = new MetaData(new TemplateData(__YOUR_DATA__));
      private context?: LynxContext;
    
      build() {
        Column() {
          LynxView({
            // url: this.url,
            // buffer: this.buffer,
            metadata: this.metaData,
            onCreate: (context: LynxContext) => {
              const templateData: TemplateData = new TemplateData('', 'someDataProcessor');
              this.context = context;
              this.context.updateMetaData(new MetaData(templateData));
            }
          }).width('100%').height('100%');
        }
        .size({ width: '100%', height: '100%' })
      }
    }

    因此,你定义的一个命名的 dataProcessor 将被调用来处理 initData,你可以使用以下语法定义多个 dataProcessor

    src/index.tsx
    import { root } from '@lynx-js/react';
    import { App } from './App.js';
    
    lynx.registerDataProcessors({
      dataProcessors: {
        someDataProcessor: function (rawInitData) {
          // process rawInitData
          returnprocessedInitData;
        },
        anotherDataProcessor: function (rawInitData) {
          // process rawInitData
          returnprocessedInitData;
        },
      },
    });
    root.render(<App />);
    
    if (import.meta.webpackHot) {
      import.meta.webpackHot.accept();
    }

    如果业务逻辑需要,这允许你(或宿主平台开发人员)在宿主平台上决定使用哪个 dataProcessor

    除非另有说明,本项目采用知识共享署名 4.0 国际许可协议进行许可,代码示例采用 Apache License 2.0 许可协议进行许可。