我正在使用sencha touch 本机应用。我想创建一个应该只在第一次可见的登录视图。任何建议如何解决它。
Activation.js
Ext.define('FOS.view.Activation', {
extend: 'Ext.form.Panel',
alias: "widget.activationview",
requires: ['Ext.form.FieldSet', 'Ext.form.Password', 'Ext.Label', 'Ext.Img', 'Ext.util.DelayedTask'],
config: {
title: 'Login',
items: [
{
xtype: 'label',
html: 'Activation failed. Please enter the correct credentials.',
itemId: 'activationFailedLabel',
hidden: true,
hideAnimation: 'fadeOut',
showAnimation: 'fadeIn',
style: 'color:#990000;margin:5px 0px;'
},
{
xtype: 'fieldset',
title: ' ',
items: [
{
xtype: 'textfield',
placeHolder: 'Enter Agency Id',
itemId: 'agencyIdTextField',
name: 'agencyIdTextField',
label: 'Agency Id',
labelWidth: '40%',
//required: true
},
{
xtype: 'textfield',
placeHolder: 'Enter App Id',
itemId: 'appIdTextField',
name: 'appIdTextField',
label: 'App Id',
labelWidth: '40%',
// required: true
}
]
},
{
xtype: 'button',
itemId: 'activationButton',
ui: 'action',
padding: '10px',
text: 'Activate'
}
],
listeners: [{
delegate: '#activationButton',
event: 'tap',
fn: 'onActivationButtonTap'
}]
},
onActivationButtonTap: function () {
var me = this,
agencyidField = me.down('#agencyIdTextField'),
appidField = me.down('#appIdTextField'),
label = me.down('#activationFailedLabel'),
agencyid = agencyidField.getValue(),
appid = appidField.getValue();
label.hide();
// Using a delayed task in order to give the hide animation above
// time to finish before executing the next steps.
var task = Ext.create('Ext.util.DelayedTask', function () {
label.setHtml('');
me.fireEvent('activationCommand', me, agencyid, appid);
agencyidField.setValue('');
appidField.setValue('');
});
task.delay(500);
},
showActivationFailedMessage: function (message) {
var label = this.down('#activationFailedLabel');
label.setHtml(message);
label.show();
}
});
Login.js
Ext.define('FOS.view.Login', {
extend: 'Ext.form.Panel',
alias: "widget.loginview",
requires: ['Ext.form.FieldSet', 'Ext.form.Password', 'Ext.Label', 'Ext.Img', 'Ext.util.DelayedTask'],
config: {
title: 'Login',
items: [
{
xtype: 'label',
html: 'Login failed. Please enter the correct credentials.',
itemId: 'signInFailedLabel',
hidden: true,
hideAnimation: 'fadeOut',
showAnimation: 'fadeIn',
style: 'color:#990000;margin:5px 0px;'
},
{
xtype: 'fieldset',
title: ' ',
items: [
{
xtype: 'textfield',
placeHolder: 'Enter UserName',
itemId: 'userNameTextField',
name: 'userNameTextField',
label: 'UserName',
labelWidth: '40%',
//required: true
},
{
xtype: 'passwordfield',
placeHolder: 'Enter Password',
itemId: 'passwordTextField',
name: 'passwordTextField',
label: 'Password',
labelWidth: '40%',
// required: true
}
]
},
{
xtype: 'button',
itemId: 'logInButton',
ui: 'action',
padding: '10px',
text: 'Log In'
}
],
listeners: [{
delegate: '#logInButton',
event: 'tap',
fn: 'onLogInButtonTap'
}]
},
onLogInButtonTap: function () {
var me = this,
usernameField = me.down('#userNameTextField'),
passwordField = me.down('#passwordTextField'),
label = me.down('#signInFailedLabel'),
username = usernameField.getValue(),
password = passwordField.getValue();
label.hide();
// Using a delayed task in order to give the hide animation above
// time to finish before executing the next steps.
var task = Ext.create('Ext.util.DelayedTask', function () {
label.setHtml('');
me.fireEvent('signInCommand', me, username, password);
usernameField.setValue('');
passwordField.setValue('');
});
task.delay(500);
},
showSignInFailedMessage: function (message) {
var label = this.down('#signInFailedLabel');
label.setHtml(message);
label.show();
}
});
MainMenu.js
Ext.define('FOS.view.MainMenu', {
extend: 'Ext.Panel',
requires: ['Ext.TitleBar'],
alias: 'widget.mainmenuview',
config: {
layout: {
type: 'fit'
},
items: [{
xtype: 'titlebar',
title: 'Main Menu',
docked: 'top',
items: [
{
xtype: 'button',
text: 'Log Off',
itemId: 'logOffButton',
align: 'right'
}
]
}],
listeners: [{
delegate: '#logOffButton',
event: 'tap',
fn: 'onLogOffButtonTap'
}]
},
onLogOffButtonTap: function () {
this.fireEvent('onSignOffCommand');
}
});
控制器
Ext.define('FOS.controller.Login', {
extend: 'Ext.app.Controller',
config: {
refs: {
loginView: 'loginview',
mainMenuView: 'mainmenuview',
activationView: 'activationview'
},
control: {
activationView: {
activationCommand: 'onActivationCommand'
},
loginView: {
signInCommand: 'onSignInCommand'
},
mainMenuView: {
onSignOffCommand: 'onSignOffCommand'
}
}
},
// Session token
// sessionToken: null,
// Transitions
getSlideLeftTransition: function () {
return { type: 'slide', direction: 'left' };
},
getSlideRightTransition: function () {
return { type: 'slide', direction: 'right' };
},
onActivationCommand: function (view, agencyid, appid) {
console.log('AgencyId: ' + agencyid + '\n' + 'AppId: ' + appid);
var me = this,
activationView = me.getActivationView();
if (agencyid.length === 0 || appid.length === 0) {
activationView.showActivationFailedMessage('Please enter your Agency Id and App Id.');
return;
}
activationView.setMasked({
xtype: 'loadmask',
message: 'Activating...'
});
me.activationSuccess(); //Just simulating success.
},
activationSuccess: function () {
console.log('Activated.');
var activationView = this.getActivationView();
loginView = this.getLoginView();
activationView.setMasked(false);
Ext.Viewport.animateActiveItem(loginView, this.getSlideLeftTransition());
},
onSignInCommand: function (view, username, password) {
console.log('Username: ' + username + '\n' + 'Password: ' + password);
var me = this,
loginView = me.getLoginView();
if (username.length === 0 || password.length === 0) {
loginView.showSignInFailedMessage('Please enter your User Name and Password.');
return;
}
loginView.setMasked({
xtype: 'loadmask',
message: 'Signing In...'
});
/* Ext.Ajax.request({
url: '../../services/login.ashx',
method: 'post',
params: {
user: username,
pwd: password
},
success: function (response) {
var loginResponse = Ext.JSON.decode(response.responseText);
if (loginResponse.success === "true") {
// The server will send a token that can be used throughout the app to confirm that the user is authenticated.
me.sessionToken = loginResponse.sessionToken;*/
me.signInSuccess(); //Just simulating success.
/* } else {
me.singInFailure(loginResponse.message);
}
},
failure: function (response) {
me.sessionToken = null;
me.singInFailure('Login failed. Please try again later.');
}
});*/
},
signInSuccess: function () {
console.log('Signed in.');
var loginView = this.getLoginView();
mainMenuView = this.getMainMenuView();
loginView.setMasked(false);
Ext.Viewport.animateActiveItem(mainMenuView, this.getSlideLeftTransition());
},
/*
singInFailure: function (message) {
var loginView = this.getLoginView();
loginView.showSignInFailedMessage(message);
loginView.setMasked(false);
},*/
onSignOffCommand: function () {
var me = this;
/* Ext.Ajax.request({
url: '../../services/logoff.ashx',
method: 'post',
params: {
sessionToken: me.sessionToken
},
success: function (response) {
// TODO: You need to handle this condition.
},
failure: function (response) {
// TODO: You need to handle this condition.
}
});*/
Ext.Viewport.animateActiveItem(this.getLoginView(), this.getSlideRightTransition());
}
});
app.js
//<debug>
Ext.Loader.setPath({
'Ext': 'touch/src',
'FOS': 'app'
});
//</debug>
Ext.application({
controllers: ["Login"],
name: 'FOS',
requires: [
'Ext.MessageBox'
],
views: ['Activation','Login','MainMenu'],
icon: {
'57': 'resources/icons/Icon.png',
'72': 'resources/icons/Icon~ipad.png',
'114': 'resources/icons/Icon@2x.png',
'144': 'resources/icons/Icon~ipad@2x.png'
},
isIconPrecomposed: true,
startupImage: {
'320x460': 'resources/startup/320x460.jpg',
'640x920': 'resources/startup/640x920.png',
'768x1004': 'resources/startup/768x1004.png',
'748x1024': 'resources/startup/748x1024.png',
'1536x2008': 'resources/startup/1536x2008.png',
'1496x2048': 'resources/startup/1496x2048.png'
},
launch: function() {
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
// Initialize the main view
Ext.Viewport.add([
{ xtype: 'activationview'},
{ xtype: 'mainmenuview' },
{ xtype: 'loginview' }
]);
},
onUpdated: function() {
Ext.Msg.confirm(
"Application Update",
"This application has just successfully been updated to the latest version. Reload now?",
function(buttonId) {
if (buttonId === 'yes') {
window.location.reload();
}
}
);
}
});
我只希望这个激活视图一次。 网络服务尚不可用....
答案 0 :(得分:7)
基本上,您所寻找的内容类似于大多数网站和原生应用上提供的记住我或 SSO (单点登录)功能。我自己最近在我的应用程序中需要这个。
使用sencha,您可以使用HTML5存储。用户成功登录后,将某些用户详细信息(如登录状态,访问令牌,用户ID等)存储到HTML5数据库中。您可以轻松地在其中存储多达5MB的数据,并且由于sencha在webkit等现代Web浏览器上运行,您可以使用该API并使用它来完成任务。
所以到目前为止,我已经在我的应用中创建了一个包含用户ID,登录状态和访问令牌等各种字段的模型。例如,您可以使用类似 -
的模型Ext.define('MyApp.model.Userinfo',{
extend:'Ext.data.Model',
config:{
identifier: 'uuid',
store:'MyApp.store.Userinfo',
fields:[
{name: 'id', type: 'string' },
{name: 'userid', type: 'string' },
{name:'login_status',type:'string'},
{name:'access_token',type:'string'}
]
}
});
您可以根据需要添加字段数,并为每个字段选择合适的类型。但是你的模型应该有一个唯一的标识符。使用ST2.0,您可以使用identifier:'uuid'
为存储分配唯一标识符。
然后是商店,它可以像 -
Ext.define('MyApp.store.Userinfo',{
extend:'Ext.data.Store',
config:{
model:'MyApp.model.Userinfo',
autoLoaded:true,
autoLoad: true,
autoSave:true,
proxy:{
type:'localstorage',
id:'userinfo'
}
}
});
最后,当登录成功时,您可以使用 -
将数据添加到localstorage中 var userInfoData=Ext.getStore('Userinfo');
userInfoData.removeAll();
userInfoData.getProxy().clear();
userInfoData.add({userid:'user_id_to_store',login_status:"true",access_token:'generated_access_token'});
userInfoData.sync();
最后,在app.js
中,检查此本地存储的条目并验证访问令牌的可靠性。所以在launch
方法中,
var userInfoData=Ext.getStore('Userinfo');
if(null!=userInfoData.getAt(0)){
var status = userInfoData.getAt(0).get('login_status');
var user_id=userInfoData.getAt(0).get('userid');
var access_token = userInfoData.getAt(0).get('access_token');
//validate access token, check user id and status and load your next view that comes after login
}else{
// if reached here, that means user is not logged in.
// load your login view.
}
我无法读取您的整个代码并对其进行编辑。但这就是我用过的,直到现在它都没有任何麻烦。您可以根据自己的应用和要求轻松更改它。
<强>注意强>
此代码已有一年多的历史了。所以它可能不适用于最新的ST版本(未经测试)。 但想法是一样的。干杯。 :)