使用 NativeScript 基于 JavaScript 构建原生应用

pdce 9年前

有很多可供利用 HTML CSS 和 JavaScript,来创建跨平台的应用程序,我已经在这些之前找到了很多。在这篇文章中我将讨论 Telerik 所说的比许多现有的更容易创建跨平台的应用程序 ——nativescript。

从官方文档来看

开发者使用 nativescript 对 iOS、Android、Windows 建立通用本地应用程序,跨平台共享应用程序代码。构建应用程序 UI 时,开发者使用我们的库文件,它抽象出本地平台之间的差异。

创建一个图片搜索 flicker app

本教程中,我们将创建一个简单的 APP,用 flickr 搜索图片并且显示结果,我们将利用 flicker 开发者 API 搜索图片。

本教程源码在 GitHub

入门

安装 nodejs 并使用 node 包管理器 (npm) 安装 native script。

npm install -g nativescript

装好之后,创建一个新的项目,叫做 NativeApp

tns create NativeApp

导航至项目路径,使用命令行添加移动开发平台。

tns platform add android

在 android 模拟器上运行应用程序。

tns run android --emulator

使用 NativeScript 基于 JavaScript 构建原生应用

    项目结构

使用 NativeScript 基于 JavaScript 构建原生应用

项目目录里面有 3 个子目录:applib 和 platforms。应用程序代码位于 app 目录。应用程序代码是使用 JavaScript 写的,而用户界面则使用 XML 进行设计。

app 目录里面是一个叫做 main-page.xml  的文件,它是用户界面的默认代码。在 main-view-model.js 中是默认的模型代码,而 main-page.js 定义了应用程序逻辑。最后 app.js 包含了使用定义好的模型启动应用程序的代码。

设计应用

让我们先从使用 XML 设计应用开始吧。打开 main-page.xml 并观察默认代码。除了 page 标记以外其它都删除。page 标记有一个叫做 loaded 的属性,它会在应用一加载就执行 pageLoaded 函数。pageLoaded 函数位于 main-page.js 文件中。

本项目使用了一个栈布局来设计我们的应用。还有许多的 NativeScript布局

在page标记中添加栈布局。

<StackLayout orientation="vertical">     </StackLayout>

使用一个竖向(vertical)的 orientation 定义栈布局。在栈布局立面加入一个文本框和一个按钮。

<TextField width="300px" hint="search keyword" />     <Button text="Search" height="50px" style="background-color:green;width:300px;border:none;font-size:20px;" />

保存并运行应用。看起来一个像下面这样。

使用 NativeScript 基于 JavaScript 构建原生应用

从 flickr 获取数据

在搜索按钮中加入一个叫做 tap 的属性

tap="signin"

现在,当用户触摸搜索按钮时,signin 函数就会被调用。让我们在 main-page.js 中定义 signin 函数。

exports.signin = function() {    // Code would be here !  };

为了能使用 flickr 的开发者 API,你需要一个免费的 flickr 账户。请求一个 API key 以发起 API 请求。

在 main-page.js 定义 API key。

var api_key = 'replacewithyourkey';

调用 API 需要用到 http 模块,所以把模块导入 main-page.js

var http = require("http");

在 sigin 函数里面,使用 http 模块,发起 API 调用请求。

http.getJSON("https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=" + api_key + "&text=hello&format=json&nojsoncallback=1&per_page=5").then(function(r) {         console.log(JSON.stringify(r));     }, function(e) {         console.log(e);     });

上面代码暂时使用硬编码的搜索文本发起 API 调用请求,教程中稍后会变成动态获取的文本.

在模拟器运行应用时,你会需要运行 ‘adb logcat’ 来检查日志消息。

保存并运行. 点击搜索按钮,从 Flickr 返回的结果应该在终端上可见了.

接下来使用返回的响应创建图像的 url,并将其放入图像数组.

可观察的数据被用来创建一些事物的集合,并监听变化的发生。将相同的同一个可观察的数组绑定到视图,那样变化发生时视图就会更新了。

要创建可观察数据,可以在 main-page.js 中添加如下的变量声明 :

var observableArray = require("data/observable-array");  var images = new observableArray.ObservableArray([]);

基于从 API 请求返回的响应,下一步是创建 flickr 图片 URL。可以从这儿找到有关创建 flickr URL 的相关信息。

接下来我们对返回的数据进行遍历, 创建图像 URL 并放入图像数组。在 signin 函数中放入这些代码。

var imgUrl = '';     var photoList = r.photos.photo;     for (var i = 0; i < photoList.length; i++) {      imgUrl = "https://farm" + photoList[i].farm + ".staticflickr.com/" + photoList[i].server + "/" + photoList[i].id + "_" + photoList[i].secret + ".jpg";         images.push({          img: imgUrl      });     }

将数据绑定到 UI

图像数组里面有了数据,就可以绑定到UI了。为了能展现数据,在 main-page.xml 中创建一个 ListView , 就在现有的 Button 元素底下。

<ListView>      <ListView.itemTemplate>             <Image stretch="fill" height="200px" />         </ListView.itemTemplate>  </ListView>

将图像数组绑定到 list 视图,设置图片的来源(src)。

 <ListView items="{{ images }}">      <ListView.itemTemplate>             <Image stretch="fill" height="200px" src="{{img}}" />         </ListView.itemTemplate>  </ListView>

为了让图像数组在整个视图上可用,在 observable 模块中设置图像数组。为此导入 observable 模块,并用它来创建一个 observable 对象。

var observableModule = require("data/observable");  var pageData = new observableModule.Observable();

在 pageLoaded 函数中将图像数组设置到 observable 模块,并将模块添加到页面上下文中。

function pageLoaded(args) {      var page = args.object;      pageData.set("images", images);      page.bindingContext = pageData;  }

使用相同的 pageData observable 对象,来自搜索文本框的值就可以被读取。修改文本域,加入 text 属性。

<TextField width="300px" text="{{txtKeyword}}"  hint="search keyword"/>

signin 函数中要删除硬编码的 hello 搜索文本,并像下面这样替换它:

pageData.get('txtKeyword')

保存并运行。点击搜索按钮,从 Flickr API 收到的图像就可以被看到了。请求返回了 5 张图片,因此向下滑动应该能看到所有的图片。

使用 NativeScript 基于 JavaScript 构建原生应用

总结

教程展示了如何开始使用 NativeScript 创建一个简单的移动应用。有关使用 NatieScript 的详细信息,我建议阅读 官方文档

你有使用 NativeScript 进行移动开发的经历吗? 使用它时你有什么感想 ? 让我们在评论中知道你的观点,建议以及修改意见。