使用 NativeScript 基于 JavaScript 构建原生应用
有很多可供利用 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
项目结构
项目目录里面有 3 个子目录:app, lib 和 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;" />
保存并运行应用。看起来一个像下面这样。
从 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 创建一个简单的移动应用。有关使用 NatieScript 的详细信息,我建议阅读 官方文档。
你有使用 NativeScript 进行移动开发的经历吗? 使用它时你有什么感想 ? 让我们在评论中知道你的观点,建议以及修改意见。