English document From http://shripalsoni.com/blog/nativescript-webview-native-bi-directional-communication/javascript
Nativescript 提供跨平台的 web 视图 ui 元素。它为在咱们的页面中显示 web 视图内容提供了服务。
可是, 若是您但愿将一些数据发送到 web 视图或从 web 视图获取一些数据, 则须要为此编写特定于平台的代码。所以, 与其在每一个应用程序中编写全部这样的代码, 不若有一个插件。对?html
我已经建立了nativescript web 视图接口插件以实现此目的。您能够克隆演示应用程序, 以便快速入门使用此插件。
演示应用的输出以下所示:java
在这个演示应用程序中, 咱们在 web 视图中有语言下拉列表, 咱们能够在下拉菜单中添加新的语言和查询语言, 从本机侧面。每当选定内容发生更改时, 下拉列表也会向本机发出事件。android
让咱们理解一下, 这是如何工做的。ios
首先, 咱们须要按照https://www.npmjs.com/package/nativescript-webview-interface#installation)中的指令安装插件.
一旦安装了插件, 让咱们添加web-view
元素到咱们的页面。git
main-page.xml
github
<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 中的相关代码。)web
main-page.ts
typescript
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
供参考。npm
假设咱们按照上面提到的安装说明复制了 web 视图的插件文件, 让咱们将插件文件导入到咱们的index.html
www/index.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
(function(){ // oWebViewInterface provides necessary APIs for communication to native app. var oWebViewInterface = window.nsWebViewInterface; var languageDD = document.getElementById('knownLanguage'); function init(){ } init(); })()
如今, 咱们要加载在其中加载的一些默认语言的下拉列表。在加载 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); }
让咱们来处理loadLanguages
web 视图中的事件。
www/index.js
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); }
要让本机应用程序知道, 每当在下拉列表中更改语言时, 咱们须要从 web 视图中从选择更改中发出事件。
www/index.js
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; }); }
要在本机应用程序的下拉选项中添加新语言, 咱们能够直接调用在 web 视图中处理此操做的 JS 函数。
main-page.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]); }
在这里, 咱们打电话给addNewLanguage
web 视图的功能, 直接从本机应用程序. 请注意, 咱们要传递给的参数addNewLanguage
功能必须是数组格式。
因为咱们不指望在 web 视图中的语言添加操做有任何返回值, 因此咱们不须要将任何回调函数赋给callJSFunction
Api。
让咱们建立addNewLanguage
在 web 视图中的函数来处理此操做。
www/index.js
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(); }; }
如今, 咱们但愿从 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
function defineNativeInterfaceFunctions(){ ... window.getSelectedLanguage = function(){ var selectedLangOpt = languageDD.options[languageDD.selectedIndex]; return {id: selectedLangOpt.value, text: selectedLangOpt.text}; }; ... }
根据 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
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 接口插件。
我还建立了一个服务于有效用例的应用程序。我将在未来发布它。