鸿蒙NEXT版实战开发:前端页面调用应用侧函数(前端页面JavaScript)

往期鸿蒙全套实战精彩文章必看内容:


前端页面调用应用侧函数

开发者使用Web组件将应用侧代码注册到前端页面中,注册完成之后,前端页面中使用注册的对象名称就可以调用应用侧的函数,实现在前端页面中调用应用侧方法。

注册应用侧代码有两种方式,一种在Web组件初始化调用,使用javaScriptProxy()接口。另外一种在Web组件初始化完成后调用,使用registerJavaScriptProxy()接口。

在下面的示例中,将test()方法注册在前端页面中, 该函数可以在前端页面触发运行。

  • javaScriptProxy()接口使用示例如下。

    // xxx.ets
    import { webview } from '@kit.ArkWeb';
    
    class testClass {
      constructor() {
      }
    
      test(): string {
        return 'ArkTS Hello World!';
      }
    }
    
    @Entry
    @Component
    struct WebComponent {
      webviewController: webview.WebviewController = new webview.WebviewController();
      // 声明需要注册的对象
      @State testObj: testClass = new testClass();
    
      build() {
        Column() {
          // Web组件加载本地index.html页面
          Web({ src: $rawfile('index.html'), controller: this.webviewController})
            // 将对象注入到web端
            .javaScriptProxy({
              object: this.testObj,
              name: "testObjName",
              methodList: ["test"],
              controller: this.webviewController,
              // 可选参数
              asyncMethodList: [],
              permission: '{"javascriptProxyPermission":{"urlPermissionList":[{"scheme":"resource","host":"rawfile","port":"","path":""},' +
                          '{"scheme":"e","host":"f","port":"g","path":"h"}],"methodList":[{"methodName":"test","urlPermissionList":' +
                          '[{"scheme":"https","host":"xxx.com","port":"","path":""},{"scheme":"resource","host":"rawfile","port":"","path":""}]},' +
                          '{"methodName":"test11","urlPermissionList":[{"scheme":"q","host":"r","port":"","path":"t"},' +
                          '{"scheme":"u","host":"v","port":"","path":""}]}]}}'
            })
        }
      }
    }
  • 应用侧使用registerJavaScriptProxy()接口注册。

    // xxx.ets
    import { webview } from '@kit.ArkWeb';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    class testClass {
      constructor() {
      }
    
      test(): string {
        return "ArkUI Web Component";
      }
    
      toString(): void {
        console.log('Web Component toString');
      }
    }
    
    @Entry
    @Component
    struct Index {
      webviewController: webview.WebviewController = new webview.WebviewController();
      @State testObj: testClass = new testClass();
    
      build() {
        Column() {
          Button('refresh')
            .onClick(() => {
              try {
                this.webviewController.refresh();
              } catch (error) {
                console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
              }
            })
          Button('Register JavaScript To Window')
            .onClick(() => {
              try {
                this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"],
                        // 可选参数, asyncMethodList
                        [],
                        // 可选参数, permission
                        '{"javascriptProxyPermission":{"urlPermissionList":[{"scheme":"resource","host":"rawfile","port":"","path":""},' +
                        '{"scheme":"e","host":"f","port":"g","path":"h"}],"methodList":[{"methodName":"test","urlPermissionList":' +
                        '[{"scheme":"https","host":"xxx.com","port":"","path":""},{"scheme":"resource","host":"rawfile","port":"","path":""}]},' +
                        '{"methodName":"test11","urlPermissionList":[{"scheme":"q","host":"r","port":"","path":"t"},' +
                        '{"scheme":"u","host":"v","port":"","path":""}]}]}}'
                );
              } catch (error) {
                console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
              }
            })
          Web({ src: $rawfile('index.html'), controller: this.webviewController })
        }
      }
    }

    说明

  • 可选参数permission是一个json字符串,示例如下:

    {
      "javascriptProxyPermission": {
        "urlPermissionList": [       // Object级权限,如果匹配,所有Method都授权
          {
            "scheme": "resource",    // 精确匹配,不能为空
            "host": "rawfile",       // 精确匹配,不能为空
            "port": "",              // 精确匹配,为空不检查
            "path": ""               // 前缀匹配,为空不检查
          },
          {
            "scheme": "https",       // 精确匹配,不能为空
            "host": "xxx.com",       // 精确匹配,不能为空
            "port": "8080",          // 精确匹配,为空不检查
            "path": "a/b/c"          // 前缀匹配,为空不检查
          }
        ],
        "methodList": [
          {
            "methodName": "test",
            "urlPermissionList": [   // Method级权限
              {
                "scheme": "https",   // 精确匹配,不能为空
                "host": "xxx.com",   // 精确匹配,不能为空
                "port": "",          // 精确匹配,为空不检查
                "path": ""           // 前缀匹配,为空不检查
              },
              {
                "scheme": "resource",// 精确匹配,不能为空
                "host": "rawfile",   // 精确匹配,不能为空
                "port": "",          // 精确匹配,为空不检查
                "path": ""           // 前缀匹配,为空不检查
              }
            ]
          },
          {
            "methodName": "test11",
            "urlPermissionList": [   // Method级权限
              {
                "scheme": "q",       // 精确匹配,不能为空
                "host": "r",         // 精确匹配,不能为空
                "port": "",          // 精确匹配,为空不检查
                "path": "t"          // 前缀匹配,为空不检查
              },
              {
                "scheme": "u",       // 精确匹配,不能为空
                "host": "v",         // 精确匹配,不能为空
                "port": "",          // 精确匹配,为空不检查
                "path": ""           // 前缀匹配,为空不检查
              }
            ]
          }
        ]
      }
    }
  • index.html前端页面触发应用侧代码。

    <!-- index.html -->
    <!DOCTYPE html>
    <html>
    <body>
    <button type="button" onclick="callArkTS()">Click Me!</button>
    <p id="demo"></p>
    <script>
        function callArkTS() {
            let str = testObjName.test();
            document.getElementById("demo").innerHTML = str;
            console.info('ArkTS Hello World! :' + str);
        }
    </script>
    </body>
    </html>

复杂类型使用方法

  • 应用侧和前端页面之间传递Array。

    // xxx.ets
    import { webview } from '@kit.ArkWeb';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    class testClass {
      constructor() {
      }
    
      test(): Array<Number> {
        return [1, 2, 3, 4]
      }
    
      toString(param: String): void {
        console.log('Web Component toString' + param);
      }
    }
    
    @Entry
    @Component
    struct Index {
      webviewController: webview.WebviewController = new webview.WebviewController();
      @State testObj: testClass = new testClass();
    
      build() {
        Column() {
          Button('refresh')
            .onClick(() => {
              try {
                this.webviewController.refresh();
              } catch (error) {
                console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
              }
            })
          Button('Register JavaScript To Window')
            .onClick(() => {
              try {
                this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
              } catch (error) {
                console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
              }
            })
          Web({ src: $rawfile('index.html'), controller: this.webviewController })
        }
      }
    }
    <!-- index.html -->
    <!DOCTYPE html>
    <html>
    <body>
    <button type="button" onclick="callArkTS()">Click Me!</button>
    <p id="demo"></p>
    <script>
        function callArkTS() {
            testObjName.toString(testObjName.test());
        }
    </script>
    </body>
    </html>
  • 应用侧和前端页面之间传递基础类型,非Function等复杂类型。

    // xxx.ets
    import { webview } from '@kit.ArkWeb';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    class student {
      name: string = '';
      age: string = '';
    }
    
    class testClass {
      constructor() {
      }
    
      // 传递的基础类型name:"jeck", age:"12"。
      test(): student {
        let st: student = { name: "jeck", age: "12" };
        return st;
      }
    
      toString(param: ESObject): void {
        console.log('Web Component toString' + param["name"]);
      }
    }
    
    @Entry
    @Component
    struct Index {
      webviewController: webview.WebviewController = new webview.WebviewController();
      @State testObj: testClass = new testClass();
    
      build() {
        Column() {
          Button('refresh')
            .onClick(() => {
              try {
                this.webviewController.refresh();
              } catch (error) {
                console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
              }
            })
          Button('Register JavaScript To Window')
            .onClick(() => {
              try {
                this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
              } catch (error) {
                console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
              }
            })
          Web({ src: $rawfile('index.html'), controller: this.webviewController })
        }
      }
    }
    <!-- index.html -->
    <!DOCTYPE html>
    <html>
    <body>
    <button type="button" onclick="callArkTS()">Click Me!</button>
    <p id="demo"></p>
    <script>
        function callArkTS() {
            testObjName.toString(testObjName.test());
        }
    </script>
    </body>
    </html>
  • 应用侧调用前端页面的Callback。

    // xxx.ets
    import { webview } from '@kit.ArkWeb';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    class testClass {
      constructor() {
      }
    
      test(param: Function): void {
        param("call callback");
      }
    
      toString(param: String): void {
        console.log('Web Component toString' + param);
      }
    }
    
    @Entry
    @Component
    struct Index {
      webviewController: webview.WebviewController = new webview.WebviewController();
      @State testObj: testClass = new testClass();
    
      build() {
        Column() {
          Button('refresh')
            .onClick(() => {
              try {
                this.webviewController.refresh();
              } catch (error) {
                console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
              }
            })
          Button('Register JavaScript To Window')
            .onClick(() => {
              try {
                this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
              } catch (error) {
                console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
              }
            })
          Web({ src: $rawfile('index.html'), controller: this.webviewController })
        }
      }
    }
    <!-- index.html -->
    <!DOCTYPE html>
    <html>
    <body>
    <button type="button" onclick="callArkTS()">Click Me!</button>
    <p id="demo"></p>
    <script>
        function callArkTS() {
            testObjName.test(function(param){testObjName.toString(param)});
        }
    </script>
    </body>
    </html>
  • 应用侧调用前端页面Object里的Function。

    // xxx.ets
    import { webview } from '@kit.ArkWeb';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    class testClass {
      constructor() {
      }
    
      test(param: ESObject): void {
        param.hello("call obj func");
      }
    
      toString(param: String): void {
        console.log('Web Component toString' + param);
      }
    }
    
    @Entry
    @Component
    struct Index {
      webviewController: webview.WebviewController = new webview.WebviewController();
      @State testObj: testClass = new testClass();
    
      build() {
        Column() {
          Button('refresh')
            .onClick(() => {
              try {
                this.webviewController.refresh();
              } catch (error) {
                console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
              }
            })
          Button('Register JavaScript To Window')
            .onClick(() => {
              try {
                this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
              } catch (error) {
                console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
              }
            })
          Web({ src: $rawfile('index.html'), controller: this.webviewController })
        }
      }
    }
    <!-- index.html -->
    <!DOCTYPE html>
    <html>
    <body>
    <button type="button" onclick="callArkTS()">Click Me!</button>
    <p id="demo"></p>
    <script>
        // 写法1
        class Student {
            constructor(nameList) {
                this.methodNameListForJsProxy = nameList;
            }
            hello(param) {
                testObjName.toString(param)
            }
        }
        var st = new Student(["hello"])
        // 写法2
        //创建一个构造器,构造函数首字母大写
        function Obj1(){
            this.methodNameListForJsProxy=["hello"];
            this.hello=function(param){
                testObjName.toString(param)
            };
        }
        //利用构造器,通过new关键字生成对象
        var st1 = new Obj1();
        function callArkTS() {
            testObjName.test(st);
            testObjName.test(st1);
        }
    </script>
    </body>
    </html>
  • 前端页面调用应用侧Object里的Function。

    // xxx.ets
    import { webview } from '@kit.ArkWeb';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    class ObjOther {
      methodNameListForJsProxy: string[]
    
      constructor(list: string[]) {
        this.methodNameListForJsProxy = list
      }
    
      testOther(json: string): void {
        console.info(json)
      }
    }
    
    class testClass {
      ObjReturn: ObjOther
    
      constructor() {
        this.ObjReturn = new ObjOther(["testOther"]);
      }
    
      test(): ESObject {
        return this.ObjReturn
      }
    
      toString(param: string): void {
        console.log('Web Component toString' + param);
      }
    }
    
    @Entry
    @Component
    struct Index {
      webviewController: webview.WebviewController = new webview.WebviewController();
      @State testObj: testClass = new testClass();
    
      build() {
        Column() {
          Button('refresh')
            .onClick(() => {
              try {
                this.webviewController.refresh();
              } catch (error) {
                console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
              }
            })
          Button('Register JavaScript To Window')
            .onClick(() => {
              try {
                this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
              } catch (error) {
                console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
              }
            })
          Web({ src: $rawfile('index.html'), controller: this.webviewController })
        }
      }
    }
    <!-- index.html -->
    <!DOCTYPE html>
    <html>
    <body>
    <button type="button" onclick="callArkTS()">Click Me!</button>
    <p id="demo"></p>
    <script>
        function callArkTS() {
          testObjName.test().testOther("call other object func");
        }
    </script>
    </body>
    </html>
  • Promise场景。

    第一种使用方法,在应用侧new Promise。

    // xxx.ets
    import { webview } from '@kit.ArkWeb';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    class testClass {
      constructor() {
      }
    
      test(): Promise<string> {
        let p: Promise<string> = new Promise((resolve, reject) => {
          setTimeout(() => {
            console.log('执行完成');
            reject('fail');
          }, 10000);
        });
        return p;
      }
    
      toString(param: String): void {
        console.log(" " + param);
      }
    }
    
    @Entry
    @Component
    struct Index {
      webviewController: webview.WebviewController = new webview.WebviewController();
      @State testObj: testClass = new testClass();
    
      build() {
        Column() {
          Button('refresh')
            .onClick(() => {
              try {
                this.webviewController.refresh();
              } catch (error) {
                console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
              }
            })
          Button('Register JavaScript To Window')
            .onClick(() => {
              try {
                this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
              } catch (error) {
                console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
              }
            })
          Web({ src: $rawfile('index.html'), controller: this.webviewController })
        }
      }
    }
    <!-- index.html -->
    <!DOCTYPE html>
    <html>
    <body>
    <button type="button" onclick="callArkTS()">Click Me!</button>
    <p id="demo"></p>
    <script>
        function callArkTS() {
          testObjName.test().then((param)=>{testObjName.toString(param)}).catch((param)=>{testObjName.toString(param)})
        }
    </script>
    </body>
    </html>

    第二种使用方法,在前端页面new Promise。

    // xxx.ets
    import { webview } from '@kit.ArkWeb';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    class testClass {
    constructor() {
    }
    
    test(param:Function): void {
    setTimeout( () => { param("suc") }, 10000)
    }
    
    toString(param:String): void {
    console.log(" " + param);
    }
    }
    
    @Entry
    @Component
    struct Index {
    webviewController: webview.WebviewController = new webview.WebviewController();
    @State testObj: testClass = new testClass();
    
    build() {
    Column() {
    Button('refresh')
    .onClick(() => {
    try {
    this.webviewController.refresh();
    } catch (error) {
    console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
    }
    })
    Button('Register JavaScript To Window')
    .onClick(() => {
    try {
    this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
    } catch (error) {
    console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
    }
    })
    Web({ src: $rawfile('index.html'), controller: this.webviewController })
    }
    }
    }
    <!-- index.html -->
    <!DOCTYPE html>
    <html>
    <body>
    <button type="button" onclick="callArkTS()">Click Me!</button>
    <p id="demo"></p>
    <script>
        function callArkTS() {
          let funpromise
          var p = new Promise(function(resolve, reject){funpromise=(param)=>{resolve(param)}})
          testObjName.test(funpromise)
          p.then((param)=>{testObjName.toString(param)})
        }
    </script>
    </body>
    </html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值