You found a bug! We've classified it as TOUCH-4520 . We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.
  1. #1
    Sencha User
    Join Date
    Oct 2012
    Posts
    11
    Vote Rating
    2
    the_Chameleon is on a distinguished road

      0  

    Default history.back() is KO

    history.back() is KO


    Hello,

    I have a problem with history.back()

    Code:
    Ext.define('MyApp.controller.Apps', {    extend: 'Ext.app.Controller',
    
    
        config: {
    		refs: {
    			dataViewMenu: '#listItemMenu',
    			btBack : '#buttonReturn',
    		},
    		control: {
    			'dataViewMenu': {
    					itemtap: 'goToPage'
    			},
    			'btBack': {
    				tap: 'onBackAppView'
    			}
    		},
            routes: {
                'showView/:myView': 'showViewByAlias'
                'showView/:myView/:id': 'showDetailOffreById'
            }
        },
    	
    	onBackAppView: function() {  
    		var history = this.getApplication().getHistory();
    		history.back();
    	},
    	
    	goToPage: function(dataview, index, target, record, e, eOpts){
    		var url = record.get('url');
    		this.redirectTo(url);
    	},
    	
    	goToNewsDetails: function(dataview, index, target, record, e, eOpts){
    		var id = record.getId();
    		
    		var url = 'showView/newsDetailView/'+id;
    	
    		this.redirectTo(url);
    	},
    	
    	showViewByAlias: function(myView) {
            // set all innerItems of viewport to hidden(true)
    		// if view not exist => add this to Viewport with hidden(false)
    		// if exist => get this component and set this to hidden(false)
        },
    	
    	showDetailOffreById: function(myView, id) {
    		// load record with id @id
    		// set all innerItems of viewport to hidden(true)
    		// if view not exist => add this to Viewport with hidden(false) and record.getData()
    		// if exist => get this component and set this to hidden(false) and record.getData()
    	}
    	
    });
    My first page is a my menu list.


    Test case 1 :
    When i click the first item, my apps go to news list (route : 'showView/:myView': 'showViewByAlias'
    if i click on my back button => it's ok my app return to my menu list.


    Test case 2 :
    When i click the first item, my apps go to news list (route : 'showView/:myView': 'showViewByAlias')
    if i click on the first item of news list my apps go to news list (route :'showView/:myView/:id': 'showDetailOffreById')
    when i click again on my back button => it's KO my app doesn't return to menu list.


    menu list -> news list -> back button -> menu list => OK
    menu list -> news list -> news detail
    -> back button -> news list => OK -> back button -> menu list => KO

    Can you help me?

    when i trace history.getActions() i see that sencha has not executed actions.pop()


    Any idéa?

    test case
    Code:
    Ext.define('Test.controller.Main', {
        extend : 'Ext.app.Controller',
    
        config : {
            control : {
                'button' : {
                    tap : 'onButtonTap'
                }
            },
            routes : {
                'page1' : 'onPage1',
                'page2' : 'onPage2'
            }
        },
    
        onButtonTap : function(button) {
            var text = button.getText();
    
            switch(text) {
                case 'Go Page 1' :
                    this.redirectTo('page1');
    
                    break;
                case 'Go Page 2' :
                    this.redirectTo('page2');
    
                    break;
                case 'Back' :
                    var history = this.getApplication().getHistory();
                    debugger;
                    history.back();
    
                    break;
            }
        },
    
        onPage1 : function() {
            console.log('onPage1');
        },
    
        onPage2 : function() {
            console.log('onPage2');
        }
    });
    
    Ext.application({
        name : 'Test',
    
        controllers : [
            'Main'
        ],
    
        launch : function () {
    
            Ext.Viewport.add({
                defaultType : 'button',
                items       : [
                    {
                        text : 'Go Page 1'
                    },
                    {
                        text : 'Go Page 2'
                    },
                    {
                        text : 'Back'
                    }
                ]
            });
    
        }
    });
    Last edited by mitchellsimoens; 23 May 2013 at 8:21 AM. Reason: added test

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,647
    Vote Rating
    899
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    Thanks for the report! I have opened a bug in our bug tracker.

  3. #3
    Sencha User
    Join Date
    Oct 2012
    Posts
    11
    Vote Rating
    2
    the_Chameleon is on a distinguished road

      0  

    Default


    hello everybody,

    I think that i understood the problem.


    When we call "history.back();" Sencha go to the last url ('previousAction ') then the app will call the redirect.
    Code:
      redirectTo: function(url) {
            if (Ext.data && Ext.data.Model && url instanceof Ext.data.Model) {
                var record = url;
    
    
                url = record.toUrl();
            }
    
    
            var decoded = this.getRouter().recognize(url);
    
    
            if (decoded) {
                decoded.url = url;
                if (record) {
                    decoded.data = {};
                    decoded.data.record = record;
                }
                return this.dispatch(decoded);
            }
        },

    Then, the app will call "dispatch()" ...
    the problem isn't here?
    We know that the"addToHistory" is to true (by default)

    Code:
    dispatch: function(action, addToHistory) {
            action = action || {};
            Ext.applyIf(action, {
                application: this
            });
    
    
            action = Ext.factory(action, Ext.app.Action);
    
    
            if (action) {
                var profile    = this.getCurrentProfile(),
                    profileNS  = profile ? profile.getNamespace() : undefined,
                    controller = this.getController(action.getController(), profileNS);
    
    
                if (controller) {
                    if (addToHistory !== false) {
                        this.getHistory().add(action, true);
                    }
    
    
                    controller.execute(action);
                }
            }
        },

    So if you navigate
    page1 => page2 => page3 => back to page2 => back to page1


    the history array have this actions :


    url's action at index : 0 is page1
    url's action at index : 1 is page2
    url's action at index : 2 is page3


    back to page2 => actions.pop(); and actions.add()


    url's action at index : 0 is page1
    url's action at index : 1 is page2
    url's action at index : 2 is page2


    back to page1 => actions.pop(); and actions.add()


    url's action at index : 0 is page1
    url's action at index : 1 is page2
    url's action at index : 2 is page2


    the navigation is locked because we can't go to the first page...


    i think that we should have this.getHistory().add(action, false) when we call history.back();


    +++

  4. #4
    Sencha User
    Join Date
    Oct 2012
    Posts
    11
    Vote Rating
    2
    the_Chameleon is on a distinguished road

      0  

    Default


    I think that we have to check if the new action is a simple redirect
    or is return to last action.


    I change the function Application.dispatch(action, addToHistory)


    Code:
    dispatch: function(action, addToHistory) {
            action = action || {};
            Ext.applyIf(action, {
                application: this
            });
    
    
    
    
            action = Ext.factory(action, Ext.app.Action);
    
    
    
    
            if (action) {
                var profile    = this.getCurrentProfile(),
                    profileNS  = profile ? profile.getNamespace() : undefined,
                    controller = this.getController(action.getController(), profileNS);
    
    
    
    
                if (controller) {
                    if (addToHistory !== false) {
                        this.getHistory().add(action, true);
                    }
    
    
    
    
                    controller.execute(action);
                }
            }
        },

    to :


    Code:
     dispatch: function(action, addToHistory) {
    		console.log('call dispatch app');
            action = action || {};
            Ext.applyIf(action, {
                application: this
            });
    
    
            action = Ext.factory(action, Ext.app.Action);
    
    
            if (action) {
                var profile    = this.getCurrentProfile(),
                    profileNS  = profile ? profile.getNamespace() : undefined,
                    controller = this.getController(action.getController(), profileNS);
    
    
                if (controller) {
                    if (addToHistory !== false) {
    					// check if we have to add this action to history
    					var appHistory = this.getHistory();
    					var actions = appHistory.getActions(),
    						previousAction = actions[actions.length - 1];
    					
    					if(previousAction==undefined)
    					{
    						this.getHistory().add(action, true);
    						
    					}else{
    						// check if the action if a return to back action
    						if(action.getUrl()!==previousAction.getUrl()){
    							//the new action is not the same action than previousAction, we can add this to history
    							this.getHistory().add(action, true);
    						}					
    					}
                    controller.execute(action);
                }
    		}
          }
        },

    And IT'S OK!!!!!

    (I'm in Sencha 2.1...)

Thread Participants: 1

Tags for this Thread