将用户设置保存到设备的本地存储是移动应用的常见需求。因此,我们使使用NativeScript创建设置页面变得非常简单。在这篇博文中,您将学习如何使用 NativeScript 的最新功能(XML 声明、数据绑定和 CSS 样式)构建设置页面。为了将 UI 代码与应用的逻辑分离,我们将遵循MVVM 模式。为了演示这一点,我们将使用真实的 Fitness 应用,其源代码可在http://github.com/nativescript/sample-fitness找到。
一旦您通过使用Telerik Platform或NativeScript CLI启动并运行您的项目,我们将首先定义设置页面的视图模型。它将保存我们即将推出的健身应用所需的所有设置:姓名、体重、身高和一些通知偏好设置。
我们将使用application-settings 模块来保存和检索设备本地存储中的设置。我们将为每个属性使用不同的字符串键。
settingsViewModel也将是Observable对象,以支持双向绑定。
JS (view-model.js)
var
observable = require(
"data/observable"
);
var
appSettings = require(
"application-settings"
);
var
dialogs = require(
"ui/dialogs"
);
var
NAME =
"settings-name"
;
var
HEIGHT =
"settings-height"
;
var
WEIGHT =
"settings-weight"
;
var
VIBRATE =
"settings-vibrate"
;
var
SOUND =
"settings-sound"
;
var
SOUND_VOLUME =
"settings-sound-value"
;
var
settings =
new
observable.Observable();
Object.defineProperty(settings,
"name"
, {
get:
function
() {
return
appSettings.getString(NAME,
"John Doe"
); },
set:
function
(value) { appSettings.setString(NAME, value); },
enumerable:
true
,
configurable:
true
});
Object.defineProperty(settings,
"height"
, {
get:
function
() {
return
appSettings.getString(HEIGHT,
"180"
); },
set:
function
(value) { appSettings.setString(HEIGHT, value); },
enumerable:
true
,
configurable:
true
});
Object.defineProperty(settings,
"weight"
, {
get:
function
() {
return
appSettings.getString(WEIGHT,
"80"
); },
set:
function
(value) { appSettings.setString(WEIGHT, value); },
enumerable:
true
,
configurable:
true
});
Object.defineProperty(settings,
"vibrateEnabled"
, {
get:
function
() {
return
appSettings.getBoolean(VIBRATE,
true
); },
set:
function
(value) { appSettings.setBoolean(VIBRATE, value); },
enumerable:
true
,
configurable:
true
});
Object.defineProperty(settings,
"soundEnabled"
, {
get:
function
() {
return
appSettings.getBoolean(SOUND,
true
); },
set:
function
(value) { appSettings.setBoolean(SOUND, value); },
enumerable:
true
,
configurable:
true
});
Object.defineProperty(settings,
"soundVolume"
, {
get:
function
() {
return
appSettings.getNumber(SOUND_VOLUME, 100); },
set:
function
(value) { appSettings.setNumber(SOUND_VOLUME, value); },
enumerable:
true
,
configurable:
true
});
settings.promptName =
function
(args) {
console.log(
"in promptName"
);
dialogs.prompt(
"Enter your name:"
, settings.name).then(
function
(promptResult) {
console.log(
"prompt result:"
+ promptResult.result);
if
(promptResult.result) {
settings.set(
"name"
, promptResult.text);
}
});
}
exports.settingsViewModel = settings;
现在我们有了视图模型,是时候创建设置的 UI 了。
我们将向项目中添加两个文件
首先,我们将创建一个页面,其中包含一个空的 StackLayout,并处理 loaded 事件。在 pageLoaded 函数中,我们将页面的 bindingContext 设置为我们之前创建的视图模型:
XML(main-page.xml)
<
Page
xmlns
=
"http://www.nativescript.org/tns.xsd"
loaded
=
"pageLoaded"
>
<
StackLayout
>
...
</
StackLayout
>
</
Page
>
JavaScript(main-page.js)
var
vmModule = require(
"./view-model"
);
var
viewModel = vmModule.settingsViewModel;
function
pageLoaded(args) {
var
page = args.object;
page.bindingContext = viewModel;
}
现在让我们定义包含姓名、体重和身高的个人资料设置部分。我们将使用绑定语法将字段的文本值绑定到视图模型:
<GridLayout cssClass=
"field-group"
columns=
"auto, 50, *"
rows=
"auto, auto, auto"
>
<!-- Name -->
<Label
text=
"Name"
/>
<Button col=
"1"
colSpan=
"2"
text=
"{{ name }}"
tap=
"{{ promptName }}"
/>
<!-- 身高 -->
<Label
text=
"身高"
row=
"1"
/>
<TextField row=
"1"
col=
"1"
text=
"{{ height }}"
keyboardType=
"number"
/>
<Label col=
"2"
row=
"1"
text=
"cm"
/>
<!-- 体重 -->
<Label row=
"2"
text=
"体重"
/>
<TextField row=
"2"
col=
"1"
text=
"{{ weight }}"
keyboardType=
"number"
/>
<Label row=
"2"
col=
"2"
text=
"kg"
/>
</GridLayout>
settings.promptName =
function
(args) {
console.log(
"in promptName"
);
dialogs.prompt(
"请输入您的姓名:"
, settings.name).then(
function
(promptResult) {
console.log(
"提示结果:"
+ promptResult.result);
if
(promptResult.result) {
settings.set(
"name"
, promptResult.text);
}
});
}
结果(稍后我们将修复样式)
下一部分包含通知振动和声音的设置。我们将使用 Switch 和 Slider 控件。
XML:
<GridLayout cssClass=
"field-group"
columns=
"*, auto"
rows=
"auto, auto, auto"
>
<!-- 通知 -->
<Label cssClass=
"field"
text=
"振动"
/>
<Switch col=
"1"
cssClass=
"field-value"
checked=
"{{ vibrateEnabled }}"
/>
<!-- 通知 -->
<Label row=
"1"
cssClass=
"field"
text=
"声音"
/>
<Switch row=
"1"
col=
"1"
cssClass=
"field-value"
checked=
"{{ soundEnabled }}"
/>
<Slider row=
"2"
colSpan=
"2"
maxValue=
"100"
value=
"{{ soundVolume }}"
isEnabled=
"{{ soundEnabled }}"
/>
</GridLayout>
结果
所有功能都已就绪。剩下的就是为页面添加一些 CSS 样式。
提示:如果有一个 CSS 文件与包含 UI 声明的 XML 文件同名,它将自动应用于页面。您还可以创建一个名为 app.css 的文件并在其中定义样式,这些样式可以在应用程序中的任何页面使用。
我们需要在 XML 声明中添加一些 cssClass 属性。
...
<!-- 身高 -->
<Label cssClass=
"field"
text=
"身高"
row=
"1"
/>
<TextField row=
"1"
col=
"1"
cssClass=
"field-value"
text=
"{{ height }}"
keyboardType=
"number"
/>
<Label col=
"2"
row=
"1"
cssClass=
"field-unit"
text=
"cm"
/>
<!-- 体重 -->
<Label row=
"2"
cssClass=
"field"
text=
"体重"
/>
<TextField row=
"2"
col=
"1"
cssClass=
"field-value"
text=
"{{ weight }}"
keyboardType=
"number"
/>
<Label row=
"2"
col=
"2"
cssClass=
"field-unit"
text=
"kg"
/>
...
.field, .field-value, .field-unit, .field-dialog-button {
font-size
:
16
;
vertical-align
:
center
;
}
.field, .field-unit {
color
:
#3c3c3c
;
}
.field-value, .field-dialog-button {
color
:
#808080
;
text-align
:
right
;
}
添加标题标签和更多样式后,我们将得到以下结果
您可以在此处查看最终应用程序 - http://github.com/nativescript/sample-fitness