大家都知道MVC架构,而NativeScript框架采用的是 MVVM 模式, 即 “model view view model”。
Model: model 定义和表示数据。 将模型与可能使用它的各种视图分离允许代码重用;
View: view表示UI,它在NativeScript中用XML编写。 view通常数据绑定到view-model,因此在JavaScript中对view-model所做的更改会立即触发对UI组件的可视更改;
View Model: view model 包含应用程序逻辑(通常包括model),并将数据公开到视图view。 NativeScript提供了一个名为’Observable’的模块,它有助于创建可以绑定到视图的视图模型(view-model)对象。
code-behind 文件
这个不好翻译,就这样写吧,其实它就是一个页面视图后的js文件,要求就是和视图名称一样,如 login.xml对应login.js。
页面加载事件
现在在页面加载时执行一个函数:
<Page loaded="loaded">
在login.js里:
exports.loaded = function(){
console.log("loaded");
}
结果:
点击事件
当点击按钮时触发事件:
在button里加一个tap属性:
<Button text="Sign in" tap="signIn"/>
<Button text="Sign up for Groceries" class="link" tap = "signUp"/>
exports.signIn = function(){
alert("sign in...");
}
exports.signUp = function(){
alert("sign up...");
}
页面跳转
要使用到frame模块,下节会说。
var frameModule = require("ui/frame");
exports.signUp = function(){
var topmost = frameModule.topmost();
topmost.navigate("views/register/register");//这里不需要后缀xml
}
register.xml页面:
<Page loaded="loaded">
<StackLayout>
<Image src="res://logo" stretch="none" horizontalAlignment="center"/>
<TextField text="{{ email }}" id="email" hint="Email Address" keyboardType="email" autocorrect="false" autocapitalizationType="none" />
<TextField text="{{ password }}" secure="true" hint="Password" />
<Button text="Sign Up" tap="register" />
</StackLayout>
</Page>
数据传送
从页面(view)到逻辑(view-model)
先取到元素,再取值。
设置id
<TextField id="email" hint="Email Address" />
在login.js里:
var page;
var email;
exports.loaded = function(args){
page = args.object;
}
exports.signIn = function(){
//alert("sign in...");
email = page.getViewById("email");
console.log(email.text);
}
将数据绑定到组件元素
使用双大括号
login.xml
<TextField id="email" text="{{email}}" hint="Email Address" keyboardType="email" autocorrect="false" autocapitalizationType="none" />
<TextField hint="Password" text="{{ password}}" secure="true" />
login.js
var Observable = require("data/observable").Observable;
var user = new Observable({
email: "user@domain.com",
password: "password"
});
var page;
var email;
exports.loaded = function(args){
page = args.object;
page.bindingContext = user;
}
当页面加载时,类似保存密码功能
完整代码
目录结构
login.xml
<Page loaded="loaded">
<StackLayout>
<Label text="hello jimo" />
<Image src="res://logo" stretch="none" horizontalAlignment="center" />
<TextField id="email" text="{{email}}" hint="Email Address" keyboardType="email" autocorrect="false" autocapitalizationType="none" />
<TextField hint="Password" text="{{ password}}" secure="true" />
<Button text="Sign in" tap="signIn"/>
<Button text="Sign up for Groceries" class="link" tap = "signUp"/>
</StackLayout>
</Page>
login.js
var frameModule = require("ui/frame");
var Observable = require("data/observable").Observable;
var user = new Observable({
email: "user@domain.com",
password: "password"
});
var page;
var email;
exports.loaded = function(args){
page = args.object;
page.bindingContext = user;
}
exports.signIn = function(){
//alert("sign in...");
email = page.getViewById("email");
console.log(email.text);
}
exports.signUp = function(){
var topmost = frameModule.topmost();
topmost.navigate("views/register/register");
}
register.xml
<Page loaded="loaded">
<StackLayout>
<Image src="res://logo" stretch="none" horizontalAlignment="center"/>
<TextField text="{{ email }}" id="email" hint="Email Address" keyboardType="email" autocorrect="false" autocapitalizationType="none" />
<TextField text="{{ password }}" secure="true" hint="Password" />
<Button text="Sign Up" tap="register" />
</StackLayout>
</Page>