2012-10-29 2 views
20

Gdy główny widok mojej aplikacji jest przełączany (nowa trasa, która ponownie łączy główny wylot mojego kontrolera aplikacji), chcę, aby strona przewinęła się do góry. W przeciwnym razie jest to trochę dziwne, że przechodzę do innego widoku podobnego do strony, a widok jest nadal zagubiony w miejscu, w którym przerwałam.Emberjsy przewiń do góry, zmieniając widok

Zhakowałem rozwiązanie i zastanawiałem się, czy jest lepszy sposób, czy ktoś ma to samo.

Oto, co zrobić:

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

Odpowiedz

6

Powinieneś raczej spróbować rozszerzyć Ember.Route i dodaj swoją window.scrollTo w enter zwrotnego. Zamiast korzystać z adresu Ember Route dla tras do liści, możesz zadzwonić na swoją trasę. extend(), więc będą automatycznie przewijane w górę, gdy wprowadzi trasę/stan. Coś podobny do tego:

// 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... 
     }) 
}); 

czy to ma sens?

+0

Twoje podejście idealnie odpowiada na pytanie. Tak, wydaje się, że chodzi o trasy urlopowe, a nie o kontroler aplikacji. – xMartin

+0

Możesz także ponownie otworzyć Ember.Route i sprawdzić każde zdarzenie "enter", jeśli this.childStates.length ma wartość 0, więc wiesz, że jest to trasa urlopowa. Oba podejścia pozostawiają Tobie odpowiedzialność, aby zadzwonić do this._super, jeśli chcesz użyć zdarzenia "Enter" na określonych trasach. – xMartin

+0

Należy pamiętać, że ponowne otwarcie 'Ember.Route' polega na tym, że możesz przecenić funkcję' enter' dla ** wszystkich ** tras. Możesz zachować oryginalną funkcjonalność w ramach i rozszerzyć swoją własną bibliotekę. – MilkyWayJoe

9

I to osiągnąć za pomocą następującego kodu:

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

@ rozwiązanie Barucha jest dobra, ale kiedy wdrożony go miałem render na elementach wewnątrz mojego stanu aplikacji i spowodowałoby scrollTop kiedy to nie było potrzebne.

I okazało się, że o wiele bardziej skuteczne, ponieważ działa tylko na zmianę ścieżki:

App.ApplicationController = Ember.Controller.extend({ 

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

}); 
+0

Podoba mi się również to podejście, dziękuję za publikację. –

1

@ michael-Benin wydaje się dobrym rozwiązaniem, ale nie działa, gdy adres URL zawiera parametr jak/post/post_id.

Zmiana bieżącej ścieżce używa nazwy trasy jak „post.index” i nie zmienia się tylko w parametrze „post_id” zmienia

7

Coffee Scenariusz:

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

Javascript:

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

To, co jest tego warte, to podejście oficjalnie przepisane przez dokumenty Ember, przynajmniej w książce kucharskiej: http://guides.emberjs.com/v1.11.0/cookbook/user_interface_and_interaction/resetting_scroll_on_route_changes/ I to jest również Jedyne podejście, które zadziałało w mojej sytuacji, używając najnowszego ember-cli, musiałem stworzyć mixin i wciągnąć go na każdą dotkniętą trasę. Nie można go uruchomić na trasie aplikacji dla wszystkich tras dla dzieci. – Mattygabe

1

teraz render(name, options), a jeśli są specjalnie wywołanie render (tj modalne), które chcesz przekazać, że do super()

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