zoukankan      html  css  js  c++  java
  • [翻译]Nativescript 中 Web 视图与 Android/IOS 的双向通信

    English document From http://shripalsoni.com/blog/nativescript-webview-native-bi-directional-communication/

    Nativescript 中 Web 视图与 Android/IOS 的双向通信


    Nativescript 提供跨平台的 web 视图 ui 元素。它为在我们的页面中显示 web 视图内容提供了服务。
    但是, 如果您希望将一些数据发送到 web 视图或从 web 视图获取一些数据, 则需要为此编写特定于平台的代码。因此, 与其在每个应用程序中编写所有这样的代码, 不如有一个插件。对?

    我已经创建了nativescript web 视图接口插件以实现此目的。您可以克隆演示应用程序, 以便快速入门使用此插件。

    演示应用的输出如下所示:

    Android

    Andorid

    Ios

    在这个演示应用程序中, 我们在 web 视图中有语言下拉列表, 我们可以在下拉菜单中添加新的语言和查询语言, 从本机侧面。每当选定内容发生更改时, 下拉列表也会向本机发出事件。

    让我们理解一下, 这是如何工作的。

    步骤 1: 插件的初始化

    首先, 我们需要按照https://www.npmjs.com/package/nativescript-webview-interface#installation)中的指令安装插件.
    一旦安装了插件, 让我们添加web-view元素到我们的页面。

    main-page.xml

    Xml
    <Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded">
    ....
    <web-view id="webView" src="~/www/index.html"></web-view>
    ....
    </Page>
    

    现在, 初始化插件, 在我们的main-page.ts文件。(在这里, 我使用的是文稿, 但您可以在https://github.com/shripalsoni04/nativescript-webview-interface-demo中查看 javascript 中的相关代码。)

    main-page.ts

    文稿
    import {webViewInterfaceDemoVM} from './main-view-model';
    var webViewInterfaceModule = require('nativescript-webview-interface');
    var oLangWebViewInterface;
    
    export function pageLoaded(args){
        page = args.object;
        page.bindingContext = webViewInterfaceDemoVM;
        setupWebViewInterface(page) 
    }
    
    /**
     * Initializes webViewInterface for communication between webview and android/ios
     */
    function setupWebViewInterface(page: Page){
        var webView = page.getViewById('webView');
        oLangWebViewInterface = new webViewInterfaceModule.WebViewInterface(webView);
    }
    

    检查代码main-view-model供参考。

    假设我们按照上面提到的安装说明复制了 web 视图的插件文件, 让我们将插件文件导入到我们的index.html

    www/index.html

    Html
    <!doctype html>
    <html>
        <body>
            <select id="knownLanguage">
                <option value="-1">----Select Language----</option>
            </select>
            <script src="./lib/nativescript-webview-interface.js"></script>
            <script src="./index.js"></script>
        </body>
    </html>
    

    一旦插件文件在 html 文件中导入, 我们就可以访问所有必要的 API, 从 web 视图与本机应用程序进行通信, 在window.nsWebViewInterface全局对象。

    www/index.js

    Javascript
    (function(){
        // oWebViewInterface provides necessary APIs for communication to native app.
        var oWebViewInterface = window.nsWebViewInterface;
        var languageDD = document.getElementById('knownLanguage');
    
        function init(){
    
        }
    
        init();
    })()
    

    步骤 2: 从本机应用程序的下拉列表中加载语言

    现在, 我们要加载在其中加载的一些默认语言的下拉列表。在加载 web 视图后, 我们可以通过使用默认语言向 web 视图发出事件来执行此项设置。

    main-page.ts

    文稿
    function setupWebViewInterface(page: Page){
        ...
        // loading languages in dropdown, on load of webView.
        webView.on(WebView.loadFinishedEvent, (args: LoadEventData) => {
            if (!args.error) {
                loadLanguagesInWebView();
            }
        });
        ...       
    }
    
    /**
     * Sends intial list of languages to webView, once it is loaded 
     */
    function loadLanguagesInWebView(){
        oLangWebViewInterface.emit('loadLanguages', webViewInterfaceDemoVM.lstLanguages);
    }
    

    让我们来处理loadLanguagesweb 视图中的事件。

    www/index.js

    Javascript
    function init(){
        ...
        addNativeMsgListener();
        ...
    }
    
    /**
     * Registers handlers for native events.
     */
    function addNativeMsgListener() {
        oWebViewInterface.on('loadLanguages', function (arrLanguages) {
            for (var i = 0; i < arrLanguages.length; i++) {
                addLanguageOption(arrLanguages[i]);
            }
        });
    }
    
    /**
     *  Adds language to dropdown options 
     */
    function addLanguageOption(language){
        var option = document.createElement('Option');
        option.text = language;
        option.value = language;
        languageDD.appendChild(option);
    }
    

    步骤 3: 在下拉菜单中更改语言时通知本机应用程序

    要让本机应用程序知道, 每当在下拉列表中更改语言时, 我们需要从 web 视图中从选择更改中发出事件。

    www/index.js

    Javascript
    function init(){
        ...
        languageDD.onchange = function(){
            sendSelectedValue(languageDD.value);
        }
        ...
    
        /**
         * Sends selected value to native app by emitting an event
         */
        function sendSelectedValue(selectedLanguage){
            oWebViewInterface.emit('languageSelection', selectedLanguage);
        }
    }
    

    我们需要在本机方面处理此事件, 以便对语言更改进行任何操作。

    main-page.ts

    文稿
    function setupWebViewInterface(page: Page){
        ...    
        listenLangWebViewEvents();
        ...
    }
    
    /**
     * Handles any event/command emitted by language webview.
     */
    function listenLangWebViewEvents(){  
        // handles language selectionChange event.
        oLangWebViewInterface.on('languageSelection', (selectedLanguage) => {
            webViewInterfaceDemoVM.selectedLanguage = selectedLanguage;
        });
    }
    

    步骤 4: 从本机的下拉列表中添加新语言

    要在本机应用程序的下拉选项中添加新语言, 我们可以直接调用在 web 视图中处理此操作的 JS 函数。

    main-page.xml

    Xml
    <GridLayout rows="50" columns="*, 70">
        <TextField id="txtLanguage" col="0" hint="Language" />
        <Button col="1" text="Add" tap="addLanguage" />
    </GridLayout>
    

    main-page.ts

    文稿
    /**
     * Adds language to webView dropdown
     */
    export function addLanguage(){
        var txtField = <TextField>page.getViewById('txtLanguage');
        oLangWebViewInterface.callJSFunction('addNewLanguage', [txtField.text]);
    }
    

    在这里, 我们打电话给addNewLanguageweb 视图的功能, 直接从本机应用程序. 请注意, 我们要传递给的参数addNewLanguage功能必须是数组格式。
    由于我们不期望在 web 视图中的语言添加操作有任何返回值, 所以我们不需要将任何回调函数赋给callJSFunctionApi。

    让我们创建addNewLanguage在 web 视图中的函数来处理此操作。

    www/index.js

    Javascript
    function init(){
        ...
        defineNativeInterfaceFunctions();
        ...
    }
    
    /**
     * Defines global functions which will be called from andorid/ios
     */
    function defineNativeInterfaceFunctions(){
    
        /**
         *  Handles new language addition initiated by native app
         */
        window.addNewLanguage = function(language){
            addLanguageOption(language);
            languageDD.value = language;
            languageDD.onchange();
        };
    }
    

    步骤 5: 从 web 视图查询数据

    现在, 我们希望从 web 视图中获取当前选定语言的值。我们可以通过将 JS 函数调用到 web 视图来做到这一点。

    main-page.ts

    文稿
    /**
     * Fetches currently selected language of dropdown in webView.
     */
    export function getSelectedLanguage(){
       oLangWebViewInterface.callJSFunction('getSelectedLanguage', null, (oSelectedLang) => {
            alert(`Selected Language is ${oSelectedLang.text}`);
        });
    }
    

    www/index.js

    Javascript
    function defineNativeInterfaceFunctions(){
        ...
        window.getSelectedLanguage = function(){
            var selectedLangOpt = languageDD.options[languageDD.selectedIndex];
            return {id: selectedLangOpt.value, text: selectedLangOpt.text};
        }; 
        ...  
    }
    

    步骤 6: 从 JS 功能调用的 web 视图返回延迟结果

    根据 javscript 的异步性质, 有时我们不能在 web 视图中立即返回 js 函数的调用, 因此在这种情况下, 我们可以在 js 函数调用上返回一个承诺。
    因此, 每当承诺得到解决, 在本机应用程序端注册的回调函数将用承诺的解析值来调用。

    main-page.ts

    文稿
    /**
     * Fetches currently selected language of dropdown in webview.
     * The result will come after 2s. This function is written to show the support of deferred result.
     */
    export function getSelectedLanguageDeferred(){
       oLangWebViewInterface.callJSFunction('getSelectedLanguageDeferred', null, (oSelectedLang) => {
            alert(`Deferred Selected Language is ${oSelectedLang.text}`);
        });     
    }
    

    www/index.js

    Javascript
    function defineNativeInterfaceFunctions(){
        ...
        window.getSelectedLanguageDeferred = function(){
            var selectedLangOpt = languageDD.options[languageDD.selectedIndex];
            return new Promise(function(resolve) {
                setTimeout(function(){
                    resolve({id: selectedLangOpt.value, text: selectedLangOpt.text});        
                }, 2000);
            });
        };
        ...  
    }
    

    我知道这是非常琐碎的应用程序, 但我发现这个应用程序是正确的解释所有的方案, 可以处理 nativescript-webivew 接口插件。
    我还创建了一个服务于有效用例的应用程序。我将在将来发布它。

  • 相关阅读:
    Attributes in C#
    asp.net C# 时间格式大全
    UVA 10518 How Many Calls?
    UVA 10303 How Many Trees?
    UVA 991 Safe Salutations
    UVA 10862 Connect the Cable Wires
    UVA 10417 Gift Exchanging
    UVA 10229 Modular Fibonacci
    UVA 10079 Pizza Cutting
    UVA 10334 Ray Through Glasses
  • 原文地址:https://www.cnblogs.com/anorthwolf/p/8985133.html
Copyright © 2011-2022 走看看