HarmonyOS鸿蒙Next中webview.WebviewController传递

HarmonyOS鸿蒙Next中webview.WebviewController传递

问题描述

在父组件中使用 Web 组件,包含一个 webview.WebviewController。父组件的代码如下:

父组件:InvitationPage

// 邀请页面
import { MoreOptionPage } from './MoreOptionPage';
import { UserCollectionBar } from './UserCollectionBar';
import { webview } from '@kit.ArkWeb';
import { AppData } from '@ohos/applib';

@Entry({ routeName: 'InvitationPage' })
@Component
export struct InvitationPage {
    @State rightText: string = '...';
    @State title: string = '邀请您下载<<智慧大丰>>app';
    @State currentTabIndex: number = 0;
    @State datas: Array<string> = ['测试1', '测试2', '测试3', '测试4'];
    @State isInDeleteMode: boolean = false;
    @State isSelectAll: boolean = false;
    private tabsController: TabsController = new TabsController();
    @State isShowBottomLine: boolean = false;
    controller: webview.WebviewController = new webview.WebviewController();

    clickButton() {
        this.isShowBottomLine = !this.isShowBottomLine;
    }

    build() {
        Column() {
            UserCollectionBar({
                title: this.title,
                isInDeleteMode: this.isInDeleteMode,
                rightBtnText: this.rightText,
                rightBtnAction: () => {
                    // todo 点击之后弹出分享框和刷新等
                    this.clickButton();
                }
            });

            Web({
                src: AppData.WEB_HOST + "hd/code/index.html",
                controller: this.controller
            });

            if (this.isShowBottomLine) {
                MoreOptionPage({ webViewController: this.controller });
            }
        }.height('100%');
    }
}

子组件:MoreOptionPage

在子组件 MoreOptionPage 中,需要将父组件的 controller 传递过来,用来控制 Web 页面刷新和获取链接地址。

// H5 页面点击右上角出现的更多分享按钮
import { promptAction } from '@kit.ArkUI';
import { RouterPath, RouterUtils } from '@ohos/applib';
import { webview } from '@kit.ArkWeb';

@Component
export struct MoreOptionPage {
    @State customDialogComponentId: number = 0;
    @Prop webViewController: webview.WebviewController;

    aboutToAppear(): void {
        this.openDialog();
    }

    @Builder
    MoreOptionBar() {
        Column({ space: 40 }) {
            Row() {
                Column() {
                    // 刷新
                    Image($r('sys.media.save_button_picture')).height(30);
                    Text('刷新');
                }.height(50).onClick(() => {
                    // todo 刷新
                    this.webViewController.refresh();
                    promptAction.closeCustomDialog(this.customDialogComponentId);
                });

                Column() {
                    Image($r('sys.media.save_button_picture')).height(30);
                    Text('复制链接');
                }.height(50).onClick(() => {
                    // todo 复制链接
                    let url = this.webViewController.getUrl();
                    console.log('获取到的链接是:', url);
                    promptAction.closeCustomDialog(this.customDialogComponentId);
                });

                Column() {
                    Image($r('sys.media.save_button_picture')).height(30);
                    Text('举报');
                }.height(50).onClick(() => {
                    // todo 举报
                    const params: Record<string, string> = { 'url': 'https://www.12377.cn/' };
                    RouterUtils.pushNamedRoute(RouterPath.WebPage, params);
                    promptAction.closeCustomDialog(this.customDialogComponentId);
                });
            }.padding(20).width('100%').height(60).justifyContent(FlexAlign.Start);

            Row() {
                Text('取消').fontSize(25).margin({ bottom: 45 });
            }.onClick(() => {
                promptAction.closeCustomDialog(this.customDialogComponentId);
            }).justifyContent(FlexAlign.Center).height(45).width('100%').height(130);
        }
    }

    public openDialog() {
        promptAction.openCustomDialog({
            builder: () => { this.MoreOptionBar(); },
            offset: { dx: 0, dy: 26 },
            transition: TransitionEffect.move(TransitionEdge.BOTTOM),
            alignment: DialogAlignment.Bottom,
            cornerRadius: 0,
            width: '100%',
            onWillAppear: (() => { }),
        }).then((dialogId: number) => {
            this.customDialogComponentId = dialogId;
            console.log('DialogId Is', this.customDialogComponentId);
        });
    }

    build() {
        Column() {}.height('100%');
    }
}

遇到的问题

在调用 controller 的方法时,出现如下错误:

Device info: HUAWEI Mate 60 Pro
Build info: ALN-AL00 5.0.0.31(SP66DEVC00E32R4P7log)
Fingerprint: 655e50ebddb96cbb690df774c292f55deddb7824f98ba4b5144ae9e5568a71f4
Module name: jinhu.app.jsbc.hm
Version: 1.84
VersionCode: 20231220
PreInstalled: No
Foreground: Yes
Pid: 45297
Uid: 20020133

Reason: Error
Error name: Error
Error message: Init error. The WebviewController must be associated with a Web component
Error code: 17100001
SourceCode: let url = this.webViewController.getUrl();
^
Stacktrace: at anonymous (modules/usercenter/src/main/ets/components/pages/MoreOptionPage.ets:37:21)

解决方案

  1. 确保 WebviewController 关联到 Web 组件

    • 确保在父组件中创建的 webview.WebviewController 是在 Web 组件的上下文中使用的。
  2. 检查组件的生命周期

    • 确保在调用 webViewController 的方法时,MoreOptionPage 组件已经完全初始化。
  3. 调试和日志

    • 在调用 this.webViewController.getUrl() 之前,添加日志以确认 webViewController 是否已正确传递和初始化。
  4. 文档和示例

    • 查阅相关文档以确保使用的 API 和方法符合预期。

更多关于HarmonyOS鸿蒙Next中webview.WebviewController传递的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

错误码17100001 说明WebviewController没有和具体的Web组件关联,一个WebviewController对象只能控制一个Web组件

详细请参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-webview-V5#webviewcontroller

子组件webViewController用@Prop装饰,父组件controller就要用@State装饰,没有装饰,值传不过去,没有绑定上,详细请参考:

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-prop-V5#父组件state到子组件prop简单数据类型同步

更多关于HarmonyOS鸿蒙Next中webview.WebviewController传递的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,webview.WebviewController用于控制和管理WebView的行为。WebviewController可以通过webview.createWebviewController方法创建,并用于加载URL、执行JavaScript、处理页面导航等操作。通过传递WebviewController实例,可以在不同的组件或页面之间共享和控制同一个WebView的状态和行为,确保WebView的内容和操作在应用的不同部分保持一致。

在HarmonyOS鸿蒙Next中,WebviewController 是用于控制和操作WebView组件的核心类。要传递 WebviewController 对象,通常可以通过以下步骤实现:

  1. 创建WebView组件:首先在XML布局文件中定义WebView组件,或者在代码中动态创建。

  2. 获取WebviewController:通过 WebView 组件的 getController() 方法获取 WebviewController 实例。

  3. 传递WebviewController:将获取到的 WebviewController 对象通过方法参数、构造函数或共享变量传递给其他组件或类。

  4. 使用WebviewController:在目标类中使用传递的 WebviewController 对象来执行加载URL、执行JavaScript等操作。

通过这种方式,你可以在不同的组件或类之间共享和控制WebView的行为。

回到顶部