Flutter WebView与Angular双向通信调用JS函数iOS端报错解决方案
问题原因
报错是因为Angular 组件内定义的方法属于组件实例的私有作用域,默认不会暴露到浏览器全局window对象上,Flutter调用JS方法时默认在全局作用域检索对应函数,找不到对应方法就会抛出undefined is not a function异常。
解决步骤
1. 调整Angular侧代码,将需要暴露的方法/组件实例挂载到全局window
你可以选择挂载整个组件实例,或者只挂载需要对外暴露的单个方法:
import { Component, OnInit } from '@angular/core'; declare const window: any; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit{ title = 'testWebViewHandlers'; constructor() {} ngOnInit() { // 方式1:挂载整个组件实例到全局,自定义挂载名避免和全局变量冲突 window['flutterAccess'] = this; // 方式2:只挂载单个方法,Flutter可以直接调用fromFlutter() // window['fromFlutter'] = (newTitle: any) => this.fromFlutter(newTitle); } fromFlutter(newTitle: any) { this.title = newTitle; } }
挂载操作建议放在
ngOnInit生命周期钩子中执行,确保组件实例已经初始化完成。
2. 调整Flutter端的JS调用代码
如果用了挂载整个组件实例的方式,修改调用代码如下:
floatingActionButton: FloatingActionButton( child: const Icon(Icons.arrow_upward), onPressed: () { // webview_flutter 2.x及以下版本使用evaluateJavascript _controller.evaluateJavascript('window.flutterAccess.fromFlutter("From Flutter")'); // webview_flutter 3.x及以上版本使用runJavaScript // _controller.runJavaScript('window.flutterAccess.fromFlutter("From Flutter")'); }, ),
如果用了只挂载单个方法的方式,可直接沿用原来的调用语句:_controller.evaluateJavascript('fromFlutter("From Flutter")');
注意事项
- 建议在WebView的
onPageFinished回调触发后再执行JS调用逻辑,避免页面未加载完成、全局挂载还没执行的情况下调用报错 - 全局挂载的自定义名称不要和JS原生全局变量、第三方库的全局变量重名,避免出现变量覆盖问题
内容的提问来源于stack exchange,提问作者Mistu
相关产品推荐
相关产品推荐

