sencha touch NavigationView 源码详解(注释)

  1 Ext.define('Ext.navigation.View', {
  2     extend: 'Ext.Container',
  3     alternateClassName: 'Ext.NavigationView',
  4     xtype: 'navigationview',
  5     requires: ['Ext.navigation.Bar'],
  6     config: {
  7         /**
  8         * @cfg
  9         * @inheritdoc
 10         */
 11         baseCls: Ext.baseCSSPrefix + 'navigationview',
 12         /**
 13         * @cfg {Boolean/Object} navigationBar
 14         * 用以配置导航栏
 15         */
 16         navigationBar: {
 17             docked: 'top'
 18         },
 19         /**
 20         * @cfg {String} defaultBackButtonText
 21         * 返回按钮默认显示值
 22         */
 23         defaultBackButtonText: 'Back',
 24         /**
 25         * @cfg {Boolean} useTitleForBackButtonText
 26         * 当此值为false时,返回按钮显示值为defaultBackButtonText中设置的值
 27         * 当此值为true时,返回按钮显示值为上个项的title值
 28         * @accessor
 29         */
 30         useTitleForBackButtonText: false,
 31         /**
 32         * @cfg
 33         * @hide
 34         */
 35         layout: {
 36             type: 'card',
 37             animation: {
 38                 duration: 300,
 39                 easing: 'ease-out',
 40                 type: 'slide',
 41                 direction: 'left'
 42             }
 43         }
 44     },
 45     // @private
 46     initialize: function () {
 47         var me = this,
 48             navBar = me.getNavigationBar();
 49 
 50         //为导航栏上的后退按钮,添加监听
 51         navBar.on({
 52             back: me.onBackButtonTap,
 53             scope: me
 54         });
 55 
 56         me.relayEvents(navBar, 'rightbuttontap');
 57 
 58         me.relayEvents(me, {
 59             add: 'push',
 60             remove: 'pop'
 61         });
 62 
 63         //<debug>
 64         var layout = me.getLayout();
 65         if (layout && !layout.isCard) {
 66             Ext.Logger.error('The base layout for a NavigationView must always be a Card Layout');
 67         }
 68         //</debug>
 69     },
 70     /**
 71     * @private
 72     */
 73     applyLayout: function (config) {
 74         config = config || {};
 75 
 76         return config;
 77     },
 78     /**
 79     * @private
 80     * 用户点击返回按钮
 81     */
 82     onBackButtonTap: function () {
 83         this.pop();
 84         this.fireEvent('back', this);
 85     },
 86     /**
 87     * 添加并且显示一个新项
 88     * @return {Ext.Component} 
 89     */
 90     push: function (view) {
 91         return this.add(view);
 92     },
 93     /**
 94     * 不填写参数时,移除当前项,返回到上一项
 95     * 如果参数是数字,则从最后一项开始移除指定数目的项
 96     * 如果参数是string,则移除指定类型的项
 97     * 如果参数是项,则移除传入的项
 98     * 不论参数如何,都会保留一个活动项
 99     * @return {Ext.Component} 当前活动项
100     */
101     pop: function (count) {
102         if (this.beforePop(count)) {
103             return this.doPop();
104         }
105     },
106     /**
107     * @private
108     *删除指定项
109     */
110     beforePop: function (count) {
111         var me = this,
112             innerItems = me.getInnerItems();
113 
114         if (Ext.isString(count) || Ext.isObject(count)) {
115             var last = innerItems.length - 1,
116                 i;
117             for (i = last; i >= 0; i--) {
118                 if ((Ext.isString(count) && Ext.ComponentQuery.is(innerItems[i], count)) || (Ext.isObject(count) && count == innerItems[i])) {
119                 //获得移除项序号
120                     count = last - i;
121                     break;
122                 }
123             }
124 
125             if (!Ext.isNumber(count)) {
126                 return false;
127             }
128         }
129 
130         var ln = innerItems.length,
131             toRemove;
132 
133         //默认移除一项
134         if (!Ext.isNumber(count) || count < 1) {
135             count = 1;
136         }
137 
138         //当我们试图移除更多视图时
139         count = Math.min(count, ln - 1);
140 
141         if (count) {
142             //更新导航栏
143             me.getNavigationBar().beforePop(count);
144 
145             //开始移除视图
146             toRemove = innerItems.splice(-count, count - 1);
147             for (i = 0; i < toRemove.length; i++) {
148                 this.remove(toRemove[i]);
149             }
150 
151             return true;
152         }
153 
154         return false;
155     },
156     /**
157     * @private
158     *移除最后一项
159     */
160     doPop: function () {
161         var me = this,
162             innerItems = this.getInnerItems();
163         me.remove(innerItems[innerItems.length - 1]);
164         return this.getActiveItem();
165     },
166     /**
167     * 获取上一项
168     * @return {Mixed} 上一项
169     */
170     getPreviousItem: function () {
171         var innerItems = this.getInnerItems();
172         return innerItems[innerItems.length - 2];
173     },
174     /**
175     * 更新导航栏标题栏 {@link #navigationBar}
176     * @private
177     */
178     updateUseTitleForBackButtonText: function (useTitleForBackButtonText) {
179         var navigationBar = this.getNavigationBar();
180         if (navigationBar) {
181             navigationBar.setUseTitleForBackButtonText(useTitleForBackButtonText);
182         }
183     },
184     /**
185     * 更新后退按钮显示值 {@link #navigationBar}
186     * @private
187     */
188     updateDefaultBackButtonText: function (defaultBackButtonText) {
189         var navigationBar = this.getNavigationBar();
190         if (navigationBar) {
191             navigationBar.setDefaultBackButtonText(defaultBackButtonText);
192         }
193     },
194     // @private 初始化时添加导航栏
195     applyNavigationBar: function (config) {
196         if (!config) {
197             config = {
198                 hidden: true,
199                 docked: 'top'
200             };
201         }
202 
203         if (config.title) {
204             delete config.title;
205             //<debug>
206             Ext.Logger.warn("Ext.navigation.View: The 'navigationBar' configuration does not accept a 'title' property. You " +
207                             "set the title of the navigationBar by giving this navigation view's children a 'title' property.");
208             //</debug>
209         }
210 
211         config.view = this;
212         config.useTitleForBackButtonText = this.getUseTitleForBackButtonText();
213 
214         return Ext.factory(config, Ext.navigation.Bar, this.getNavigationBar());
215     },
216     // @private 更新导航栏
217     updateNavigationBar: function (newNavigationBar, oldNavigationBar) {
218         if (oldNavigationBar) {
219             this.remove(oldNavigationBar, true);
220         }
221 
222         if (newNavigationBar) {
223             this.add(newNavigationBar);
224         }
225     },
226     /**
227     * @private
228     */
229     applyActiveItem: function (activeItem, currentActiveItem) {
230         var me = this,
231             innerItems = me.getInnerItems();
232 
233         // 确保已经初始化
234         me.getItems();
235 
236         // 如果没有初始化,将堆栈中最后一项设置为活动
237         if (!me.initialized) {
238             activeItem = innerItems.length - 1;
239         }
240 
241         return this.callParent([activeItem, currentActiveItem]);
242     },
243     doResetActiveItem: function (innerIndex) {
244         var me = this,
245             innerItems = me.getInnerItems(),
246             animation = me.getLayout().getAnimation();
247 
248         if (innerIndex > 0) {
249             if (animation && animation.isAnimation) {
250                 animation.setReverse(true);
251             }
252             me.setActiveItem(innerIndex - 1);
253             me.getNavigationBar().onViewRemove(me, innerItems[innerIndex], innerIndex);
254         }
255     },
256     /**
257     * @private 
258     *执行移除项,调用remove方法后自动执行
259     */
260     doRemove: function () {
261         var animation = this.getLayout().getAnimation();
262 
263         if (animation && animation.isAnimation) {
264             animation.setReverse(false);
265         }
266 
267         this.callParent(arguments);
268     },
269     /**
270     * @private 
271     *执行添加项,调用add方法后自动执行
272     */
273     onItemAdd: function (item, index) {
274         this.doItemLayoutAdd(item, index);
275 
276         if (!this.isItemsInitializing && item.isInnerItem()) {
277             this.setActiveItem(item);
278             this.getNavigationBar().onViewAdd(this, item, index);
279         }
280 
281         if (this.initialized) {
282             this.fireEvent('add', this, item, index);
283         }
284     },
285     /**
286     * 移除第一项和最后项之间的所有项(包括最后项)
287     * @return {Ext.Component} 当前活动视图
288     */
289     reset: function () {
290         return this.pop(this.getInnerItems().length);
291     }
292 });

 

posted @ 2013-10-18 16:57  魔狼再世  阅读(1650)  评论(0编辑  收藏  举报