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 接口插件。
我還建立了一個服務於有效用例的應用程序。我將在未來發布它。