sencha touch NavigationView 源码详解(注释)

时间:2023-03-09 03:23:57
sencha touch NavigationView 源码详解(注释)
 Ext.define('Ext.navigation.View', {
extend: 'Ext.Container',
alternateClassName: 'Ext.NavigationView',
xtype: 'navigationview',
requires: ['Ext.navigation.Bar'],
config: {
/**
* @cfg
* @inheritdoc
*/
baseCls: Ext.baseCSSPrefix + 'navigationview',
/**
* @cfg {Boolean/Object} navigationBar
* 用以配置导航栏
*/
navigationBar: {
docked: 'top'
},
/**
* @cfg {String} defaultBackButtonText
* 返回按钮默认显示值
*/
defaultBackButtonText: 'Back',
/**
* @cfg {Boolean} useTitleForBackButtonText
* 当此值为false时,返回按钮显示值为defaultBackButtonText中设置的值
* 当此值为true时,返回按钮显示值为上个项的title值
* @accessor
*/
useTitleForBackButtonText: false,
/**
* @cfg
* @hide
*/
layout: {
type: 'card',
animation: {
duration: 300,
easing: 'ease-out',
type: 'slide',
direction: 'left'
}
}
},
// @private
initialize: function () {
var me = this,
navBar = me.getNavigationBar(); //为导航栏上的后退按钮,添加监听
navBar.on({
back: me.onBackButtonTap,
scope: me
}); me.relayEvents(navBar, 'rightbuttontap'); me.relayEvents(me, {
add: 'push',
remove: 'pop'
}); //<debug>
var layout = me.getLayout();
if (layout && !layout.isCard) {
Ext.Logger.error('The base layout for a NavigationView must always be a Card Layout');
}
//</debug>
},
/**
* @private
*/
applyLayout: function (config) {
config = config || {}; return config;
},
/**
* @private
* 用户点击返回按钮
*/
onBackButtonTap: function () {
this.pop();
this.fireEvent('back', this);
},
/**
* 添加并且显示一个新项
* @return {Ext.Component}
*/
push: function (view) {
return this.add(view);
},
/**
* 不填写参数时,移除当前项,返回到上一项
* 如果参数是数字,则从最后一项开始移除指定数目的项
* 如果参数是string,则移除指定类型的项
* 如果参数是项,则移除传入的项
* 不论参数如何,都会保留一个活动项
* @return {Ext.Component} 当前活动项
*/
pop: function (count) {
if (this.beforePop(count)) {
return this.doPop();
}
},
/**
* @private
*删除指定项
*/
beforePop: function (count) {
var me = this,
innerItems = me.getInnerItems(); if (Ext.isString(count) || Ext.isObject(count)) {
var last = innerItems.length - 1,
i;
for (i = last; i >= 0; i--) {
if ((Ext.isString(count) && Ext.ComponentQuery.is(innerItems[i], count)) || (Ext.isObject(count) && count == innerItems[i])) {
//获得移除项序号
count = last - i;
break;
}
} if (!Ext.isNumber(count)) {
return false;
}
} var ln = innerItems.length,
toRemove; //默认移除一项
if (!Ext.isNumber(count) || count < 1) {
count = 1;
} //当我们试图移除更多视图时
count = Math.min(count, ln - 1); if (count) {
//更新导航栏
me.getNavigationBar().beforePop(count); //开始移除视图
toRemove = innerItems.splice(-count, count - 1);
for (i = 0; i < toRemove.length; i++) {
this.remove(toRemove[i]);
} return true;
} return false;
},
/**
* @private
*移除最后一项
*/
doPop: function () {
var me = this,
innerItems = this.getInnerItems();
me.remove(innerItems[innerItems.length - 1]);
return this.getActiveItem();
},
/**
* 获取上一项
* @return {Mixed} 上一项
*/
getPreviousItem: function () {
var innerItems = this.getInnerItems();
return innerItems[innerItems.length - 2];
},
/**
* 更新导航栏标题栏 {@link #navigationBar}
* @private
*/
updateUseTitleForBackButtonText: function (useTitleForBackButtonText) {
var navigationBar = this.getNavigationBar();
if (navigationBar) {
navigationBar.setUseTitleForBackButtonText(useTitleForBackButtonText);
}
},
/**
* 更新后退按钮显示值 {@link #navigationBar}
* @private
*/
updateDefaultBackButtonText: function (defaultBackButtonText) {
var navigationBar = this.getNavigationBar();
if (navigationBar) {
navigationBar.setDefaultBackButtonText(defaultBackButtonText);
}
},
// @private 初始化时添加导航栏
applyNavigationBar: function (config) {
if (!config) {
config = {
hidden: true,
docked: 'top'
};
} if (config.title) {
delete config.title;
//<debug>
Ext.Logger.warn("Ext.navigation.View: The 'navigationBar' configuration does not accept a 'title' property. You " +
"set the title of the navigationBar by giving this navigation view's children a 'title' property.");
//</debug>
} config.view = this;
config.useTitleForBackButtonText = this.getUseTitleForBackButtonText(); return Ext.factory(config, Ext.navigation.Bar, this.getNavigationBar());
},
// @private 更新导航栏
updateNavigationBar: function (newNavigationBar, oldNavigationBar) {
if (oldNavigationBar) {
this.remove(oldNavigationBar, true);
} if (newNavigationBar) {
this.add(newNavigationBar);
}
},
/**
* @private
*/
applyActiveItem: function (activeItem, currentActiveItem) {
var me = this,
innerItems = me.getInnerItems(); // 确保已经初始化
me.getItems(); // 如果没有初始化,将堆栈中最后一项设置为活动
if (!me.initialized) {
activeItem = innerItems.length - 1;
} return this.callParent([activeItem, currentActiveItem]);
},
doResetActiveItem: function (innerIndex) {
var me = this,
innerItems = me.getInnerItems(),
animation = me.getLayout().getAnimation(); if (innerIndex > 0) {
if (animation && animation.isAnimation) {
animation.setReverse(true);
}
me.setActiveItem(innerIndex - 1);
me.getNavigationBar().onViewRemove(me, innerItems[innerIndex], innerIndex);
}
},
/**
* @private
*执行移除项,调用remove方法后自动执行
*/
doRemove: function () {
var animation = this.getLayout().getAnimation(); if (animation && animation.isAnimation) {
animation.setReverse(false);
} this.callParent(arguments);
},
/**
* @private
*执行添加项,调用add方法后自动执行
*/
onItemAdd: function (item, index) {
this.doItemLayoutAdd(item, index); if (!this.isItemsInitializing && item.isInnerItem()) {
this.setActiveItem(item);
this.getNavigationBar().onViewAdd(this, item, index);
} if (this.initialized) {
this.fireEvent('add', this, item, index);
}
},
/**
* 移除第一项和最后项之间的所有项(包括最后项)
* @return {Ext.Component} 当前活动视图
*/
reset: function () {
return this.pop(this.getInnerItems().length);
}
});