ionic framework - paginas - Iónico anula todo el comportamiento del botón BACK para un controlador específico
navegar entre paginas ionic 3 (6)
¿Estás hablando de la navegación suave como en el botón Atrás en el ion-header-bar o ion-nav-bar? porque es una solución fácil. Solo crea tu propia barra de encabezado personalizada para esa plantilla. entonces esa plantilla de estado solo usa algo como esto.
<div class="bar bar-header bar-positive">
<button ng-click="someCustomFunction()" class="button button-clear button-light icon-left ion-chevron-left">Go Back</button>
</div>
Quiero poder anular el botón ATRÁS en la barra de navegación y el botón de hardware.
Quiero que esta anulación sea para un controlador específico, pero no para el resto de los controladores.
- debe ser cancelado cuando el usuario se mueve a otra pantalla
(usando iónico v1.0.0 uranio-unicornio)
Mi razón es que tengo una lista de artículos. Al hacer clic en la lista, se abre una página de detalles, con 3 pestañas. Cada pestaña comparte el mismo controlador.
Sin embargo, presionar ATRÁS en cualquiera de esas pestañas debe volver a la lista principal. Así es como funciona en dispositivos nativos, así es como me gustaría que funcione en mi aplicación híbrida.
Muchas soluciones proporcionadas en línea parecen ser para versiones beta más antiguas o para el registro fuera de los controladores.
Una solución común para trabajar con el botón de hardware de Android dentro de un controlador es:
$ionicPlatform.registerBackButtonAction(function (event) {
if($state.current.name=="home"){
alert("button back");
}
}, 100);
Sin embargo, esto no parece funcionar en el botón de la barra de navegación, y funciona en todos los controladores, no solo en el uno.
La respuesta anterior para anular $ rootScope. $ IonicGoBack funciona parcialmente.
El problema es con la forma de desregistrarSoftBack. Probé el mencionado $ scope. $ On (''$ destroy'', a_function) y también el nuevo $ scope. $ On (''$ ionicView.beforeLeave'', a_function), ninguno funciona.
El motivo: el nuevo controlador se ingresará antes del desregistroSoftBack, por lo tanto, hará que el registro fallido falle. Así que modifiqué la solución un poco para que funcione.
cambiar el
var oldSoftBack = $rootScope.$ionicGoBack
a
$rootScope.oldSoftBack = $rootScope.$ionicGoBack
Desregistrar en $ rootScope. $ on ("$ stateChangeStart", your_function), el código es:
if ($rootScope.oldSoftBack) { $rootScope.$ionicGoBack = $rootScope.oldSoftBack; $rootScope.oldSoftBack = null; }
Recibió los comentarios de @ raven.zuo e hizo algunas correcciones para anular el registro del evento de cambio de estado.
(function () {
''use strict'';
angular
.module(''appName'')
.service(''customBackButtonService'', customBackButtonService);
customBackButtonService.$inject = [''$rootScope'', ''$ionicPlatform''];
function customBackButtonService($rootScope, $ionicPlatform) {
var service = {
setup: setup
};
return service;
////////////////
function setup(customBackFunction) {
// override soft back
// framework calls $rootScope.$ionicGoBack when soft back button is pressed
$rootScope.oldSoftBack = $rootScope.$ionicGoBack;
$rootScope.$ionicGoBack = function () {
customBackFunction();
};
var deregisterSoftBack = function () {
$rootScope.$ionicGoBack = $rootScope.oldSoftBack;
};
// override hard back
// registerBackButtonAction() returns a function which can be used to deregister it
var deregisterHardBack = $ionicPlatform.registerBackButtonAction(
customBackFunction, 101
);
// cancel custom back behaviour
var backStateChangeWatcher = $rootScope.$on(''$stateChangeStart'', function () {
if($rootScope.oldSoftBack){
deregisterHardBack();
deregisterSoftBack();
// Un-register watcher
backStateChangeWatcher();
}
});
}
}
})();
//Called via:
customBackButtonService.setup(function () {
console.log(''custom back'');
});
Tomé la sugerencia de Richard y la puse en servicio para que sea más reutilizable.
El controlador
angular.module(''MainApp'').controller(''MyController'', [''backButtonOverride''], function (backButtonOverride) {
// override back button for this controller
backButtonOverride.setup($scope, function() {
console.log("custom back");
});
}
El servicio
angular.module(''MainApp.services'', []).factory(''backButtonOverride'', function ($rootScope, $ionicPlatform) {
var results = {};
function _setup($scope, customBackFunction) {
// override soft back
// framework calls $rootScope.$ionicGoBack when soft back button is pressed
var oldSoftBack = $rootScope.$ionicGoBack;
$rootScope.$ionicGoBack = function() {
customBackFunction();
};
var deregisterSoftBack = function() {
$rootScope.$ionicGoBack = oldSoftBack;
};
// override hard back
// registerBackButtonAction() returns a function which can be used to deregister it
var deregisterHardBack = $ionicPlatform.registerBackButtonAction(
customBackFunction, 101
);
// cancel custom back behaviour
$scope.$on(''$destroy'', function() {
deregisterHardBack();
deregisterSoftBack();
});
}
results.setup = _setup;
return results;
});
esta es mi solución :)
Coloque esta parte del código en su función de ejecución de app.js:
//** Go Back interception function ------------------------------------------
var currentScope;
var defaultGoBack = $rootScope.$ionicGoBack;
$rootScope.$ionicGoBack = function() {
if ( angular.isFunction( currentScope.customGoBack ) ) {
//assign default go back function to as a "super" function ^^
currentScope.customGoBack.super = defaultGoBack;
//if there is a custom back function, execute-it
currentScope.customGoBack();
} else {
//else, execute default go back
defaultGoBack();
}
};
//Store targetScope to global each time the view is changing
$rootScope.$on( ''$ionicView.beforeEnter'', function( event ) {
currentScope = event.targetScope;
});
Ahora puede crear una función de devolución personalizada en los controladores:
$scope.customGoBack = function() {
console.log( "customGoBack" );
$scope.customGoBack.super();
};
Esta función se llamará automáticamente cuando el usuario toque en el botón de navegación hacia atrás.
Si desea llamar a goBack por su cuenta, puede hacerlo de esta manera:
$rootScope.$ionicGoBack();
Si desea omitir la función personalizada mientras está declarada, aquí tiene:
$ionicHistory.goBack();
Puede asignar diferentes comportamientos para el botón Atrás directamente en cada controlador :)
Es posible anular ambos botones en su controlador , sin ningún cambio en el código HTML.
Resumir:
- Botón de barra de navegación suave : reemplaza
$rootScope.$ionicGoBack()
- Botón duro de Android : use
$ionicPlatform.registerBackButtonAction()
Explicaciones detalladas a continuación.
La solución para anular la barra de navegación suave botón ATRÁS viene de entender qué hace Ionic cuando se presiona ese botón.
Desde los documentos Ionic para ion-nav-back-button
, ya sabemos que:
el botón se configura automáticamente en
$ionicGoBack()
al hacer clic / tocar.
La búsqueda en el código fuente en ionic.bundle.js revela cómo se declara esto:
$rootScope.$ionicGoBack = function(backCount) {
$ionicHistory.goBack(backCount);
};
Anular esto en su propio controlador es simple. Asegúrese de pasar $rootScope
al controlador y simplemente modifique el código anterior. Es una buena idea tomar un puntero a la función original para que pueda restaurarla si es necesario, o invocarla cuando termine su procesamiento personalizado.
// grab pointer to original function
var oldSoftBack = $rootScope.$ionicGoBack;
// override default behaviour
$rootScope.$ionicGoBack = function() {
// do something interesting here
// uncomment below line to call old function when finished
// oldSoftBack();
};
La solución para anular el botón BACK del hardware de Android , para un solo controlador, proviene del valor de retorno de la función registerBackButtonAction()
, que elimina la anulación de la anulación.
Llame a ese método de eliminación de registros en $scope.$on(''$destroy''...
handler.
var doCustomBack= function() {
// do something interesting here
};
// registerBackButtonAction() returns a function which can be used to deregister it
var deregisterHardBack= $ionicPlatform.registerBackButtonAction(
doCustomBack, 101
);
$scope.$on(''$destroy'', function() {
deregisterHardBack();
});
Más detalles aquí:
Una solución completa requeriría lo siguiente:
- anula la barra de navegación suave botón ATRÁS
- anula el botón DURO de Android
- alcance sería un solo controlador
- comportamiento predeterminado restaurado
El siguiente código ilustra cómo se puede hacer esto:
// run this function when either hard or soft back button is pressed
var doCustomBack = function() {
console.log("custom BACK");
};
// override soft back
// framework calls $rootScope.$ionicGoBack when soft back button is pressed
var oldSoftBack = $rootScope.$ionicGoBack;
$rootScope.$ionicGoBack = function() {
doCustomBack();
};
var deregisterSoftBack = function() {
$rootScope.$ionicGoBack = oldSoftBack;
};
// override hard back
// registerBackButtonAction() returns a function which can be used to deregister it
var deregisterHardBack = $ionicPlatform.registerBackButtonAction(
doCustomBack, 101
);
// cancel custom back behaviour
$scope.$on(''$destroy'', function() {
deregisterHardBack();
deregisterSoftBack();
});
Este problema se ha discutido en las páginas de foros y problemas de Ionic: