2012-10-29 11 views
20

Quando viene cambiata la vista principale dell'applicazione (nuova rotta che ricollega l'uscita principale del controller dell'applicazione) Voglio che la pagina venga spostata verso l'alto. Altrimenti è un po 'strano navigare in un'altra vista simile a una pagina e il viewport è ancora perso da qualche parte dove ho lasciato.Emberjs scorre verso l'alto quando si cambia vista

Ho violato una soluzione e mi chiedo se c'è un modo migliore o se qualcuno ha la stessa cosa.

Ecco quello che faccio:

App.ApplicationController = Ember.Controller.extend({ 
    connectOutlet: function(){ 
    window.scrollTo(0, 0); 
    this._super.apply(this, arguments); 
    } 
}); 

risposta

6

Probabilmente si dovrebbe cercare di estendere Ember.Route e aggiungere il vostro window.scrollTo nel enter callback. Quindi, invece di usare il numero Route di Ember per i percorsi delle foglie, chiami il percorso. extend(), quindi scorreranno automaticamente quando si immettere un percorso/stato. Qualcosa di simile a questo:

// define your custom route and extend "enter" 
var MyRoute = Em.Route.extend({ 
    enter: function(router) { 
     // for now on, all the routes that extend this, 
     // will fire the code in this block every time 
     // the application enters this state 
     // do whatever you need to do here: scroll and whatnot 
    } 
}); 

App.Router = Em.Router.extend({ 
    enableLogging: true, 
    location: 'hash', 
    index: Em.Route.extend({ 
      route: '/', 
      connectOutlets: function(router) { 
       ... 
      }, 
      // on your leaf routes, use your own custom route that 
      // does your scroll thing or whatever you need to do 
      home: MyRoute.extend({ 
       route: '/', 
       connectOutlets: function (router, context) { 
        ... 
       } 
      }), 
      // other routes... 
     }) 
}); 

ha senso?

+0

Il tuo approccio risponde perfettamente alla domanda. Sì, sembra riguardare i percorsi di ferie e non il controller dell'applicazione. – xMartin

+0

Puoi anche riaprire Ember.Route e controllare ogni evento "invio" se this.childStates.length è 0, quindi sai che è un percorso di partenza. Entrambi gli approcci lasciano a te la responsabilità di chiamare questo._super se è necessario utilizzare l'evento "invio" in percorsi specifici. – xMartin

+0

Ricorda che riaprire 'Ember.Route' è che ti verrebbe a sovraccaricare la funzione' enter' per ** tutti ** i percorsi. Potresti voler mantenere la funzionalità originale nel framework ed estenderla sulla tua lib. – MilkyWayJoe

9

ho raggiunto questo con il seguente codice:

Ember.Route.reopen({ 
    render: function(controller, model) { 
    this._super(); 
    window.scrollTo(0, 0); 
    } 
}); 
19

@ soluzione di Baruch è buono, ma quando ho realizzato che dovevo render su elementi all'interno del mio stato di applicazione e causerebbe una scrollTop quando non era necessario.

Ho trovato questo per essere molto più efficace in quanto viene eseguito solo sul cambiamento percorso:

App.ApplicationController = Ember.Controller.extend({ 

    currentPathChanged: function() { 
    window.scrollTo(0, 0); 
    }.observes('currentPath') 

}); 
+0

Anche questo approccio mi piace, grazie per la pubblicazione. –

1

@ michael-Bénin sembra una buona soluzione, ma non funziona quando l'URL contiene un parametro come/post/post_id.

Il cambio di percorso corrente utilizza il nome del percorso come 'post.index' e non cambia solo il parametro 'post_id' cambia

7

Caffè Script:

Ember.Route.reopen 
    activate: -> 
     @_super() 
     window.scrollTo(0, 0) 

Javascript:

Ember.Route.reopen({ 
    activate: function() { 
     this._super(); 
     window.scrollTo(0, 0); 
    } 
}); 
+0

Per quello che vale questo è l'approccio che è prescritto ufficialmente dai documenti Ember, almeno nel ricettario: http://guides.emberjs.com/v1.11.0/cookbook/user_interface_and_interaction/resetting_scroll_on_route_changes/ E questo è anche l'unico approccio che ha funzionato per la mia situazione, utilizzando l'ultima ember-cli, ho dovuto creare un mixin e inserirlo in ogni percorso interessato. Non è stato possibile attivarlo sul percorso dell'applicazione per tutte le rotte dei bambini. – Mattygabe

1

e 'ora render(name, options), e se si sta chiamando specificamente il rendering (cioè con un modale) che si desidera passare che a super()

Ember.Route.reopen({ 
    render: function(name, options) { 
    if (name != null) { 
     return this._super(name, options); 
    } else { 
     return this._super(); 
    } 
    } 
}); 
Problemi correlati