Cómo "recordar" la posición de desplazamiento en angularJS w/Ui.ROUTER
angular ui router angularjs (2)
Tengo un proyecto Estoy usando angularJS con ui.router y tenemos una lista de eventos que puede ser muy larga (tiene desplazamiento infinito) si un usuario hace clic en un evento para ver detalles, se muestra un botón Atrás pero al hacer clic atrás ¡el desplazamiento del div se restablece a la cima! Buscando algunas sugerencias sobre si hay algo incorporado que pueda aprovechar para recordar esta posición de desplazamiento, sé que hay un servicio de desplazamiento de anclas, pero me pregunto si no hay algo más adecuado para detener la restauración angular de las posiciones de desplazamiento en la navegación ?? ya que hay algunas listas similares a esto que necesitan recordar su estado cuando se desplazan .. He investigado e intentado implementar ui-router-extras dsr y sticky pero ninguno está funcionando ...
ejemplo en http://codedef.com/hapzis_poc/ . no es una prueba completa, pero debería poder desplazarse hacia abajo por los eventos, hacer clic sobre y hacia atrás y permanecer en la misma posición de desplazamiento.
Para que los estados adhesivos funcionen, no debes destruir el elemento DOM . En cuanto a la estructura de su estado, está utilizando el body
ui-view con nombre para el home
estado, según la documentación de ui-router-extras. Sin embargo, a continuación, golpea ese elemento ui-view cuando realiza la transición a about
estado about
, que también utiliza la vista general del body
. Esto se puede observar inspeccionando el DOM.
.state(''home'', {
url: "",
deepStateRedirect: true,
sticky: true,
views: {
"body": {
templateUrl: ''templates/home.html''
},
"event_list@home": {
sticky: true,
templateUrl: "templates/eventList.html",
controller: "eventListCtrl"
}
}
})
.state(''about'', {
url: ''about'',
views: {
"body": { // BAD, you just clobbered the sticky ui-view with this template
templateUrl: ''templates/about.html''
}
}
});
Asegúrese de que la vista de usuario del estado no se reutilice. Para su ejemplo, coloque el estado en la vista sin nombre.
.state(''about'', {
url: ''about'',
templateUrl: ''templates/about.html''
});
index.html:
<div ui-view="body" ng-show="$state.includes(''home'')"></div>
<div ui-view></div>
js:
app.run(function($rootScope, $state) { $rootScope.$state = $state } );
Hay una conversación sobre el tema similar ( ng-view
) y la respuesta dada por @ br2000 funcionó para mí.
https://.com/a/25073496/3959662
Para hacer que su directiva funcione para ui-router
haga lo siguiente:
1. Crea una nueva directiva como esta:
(function () {
''use strict'';
angular
.module(''your.module.directives'')
.directive(''keepScrollPos'', keepScrollPos);
function keepScrollPos($route, $window, $timeout, $location, $anchorScroll, $state) {
// cache scroll position of each route''s templateUrl
var scrollPosCache = {};
// compile function
var directive = function (scope, element, attrs) {
scope.$on(''$stateChangeStart'', function () {
// store scroll position for the current view
if($state.$current)
{
scrollPosCache[$state.current.templateUrl] = [$window.pageXOffset, $window.pageYOffset];
}
});
scope.$on(''$stateChangeSuccess'', function () {
// if hash is specified explicitly, it trumps previously stored scroll position
if ($location.hash()) {
$anchorScroll();
// else get previous scroll position; if none, scroll to the top of the page
} else {
var prevScrollPos = scrollPosCache[$state.current.templateUrl] || [0, 0];
$timeout(function () {
$window.scrollTo(prevScrollPos[0], prevScrollPos[1]);
}, 0);
}
});
};
return directive;
}
})();
2. Úselo en el elemento que tiene el atributo ui-view
, en mi caso:
<div class="col-xs-12" ui-view keep-scroll-pos></div>