Evite llamar al padre cuando anide ui-sref

Supongamos que he nested los DOM y cada uno tiene ui-sref para un estado angular-ui-router . Quiero hacer clic en externo para alertar solo externo y hacer clic en inner para alertar solo a inner. Actualmente, si hago clic en interno , alertará tanto el estado externo como el interno.

HTML:

     AngularJS Plunker document.write('');        Outer Inner    

Javascript:

 var app = angular.module('plunker', ['ui.router']); 'use strict'; app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function($stateProvider, $urlRouterProvider, $locationProvider) { $stateProvider .state("outer", { url: "/outer", resolve: { test: function() { alert("Triggered state outer"); return true; } } }) .state("inner", { url: "/inner", resolve: { test: function() { alert("Triggered state inner"); return true; } } }); }]); app.controller('MainCtrl', function($scope) { }); 

Enlace: http://plnkr.co/edit/yzgUAA3lLwkF9svzczl3?p=preview

Preguntas :

  1. ¿Cómo evitar que el interior dispare el estado externo?

  2. ¿Debo implementar algún tipo de stopImmediatePropagation para el DOM interno para que no active el ui-sref del DOM ui-sref ?

  3. ¿Hay alternativas? Tal vez usando $state.go manualmente?

ACTUALIZACIÓN 1:

No puedo cambiar HTML debido a un requisito. Esta es solo una versión simplificada porque en mi código, el elemento externo es muy grande y contiene otros elementos.

UTILIZAR ESTA…

   Outer Inner  

Esto funciona

  Outer Inner  

No sabía que puede agregar ng-click="$event.stopPropagation()" en el mismo elemento que ui-sref

Para un propósito completamente diferente, tenía una directiva stopEvent esperando a ser utilizada para el propósito nested ui-sref .

  Outer Inner  

Esta es la directiva

 app.directive('stopEvent', function () { return { restrict: 'A', link: function (scope, element, attr) { element.bind('click', function (e) { e.stopPropagation(); }); } }; }); 

¿Debo implementar algún tipo de stopImmediatePropagation para el DOM interno para que no active el ui-sref del DOM ui-sref ?

Sí exactamente.

Alternativamente, es posible que pueda reorganizar su HTML para que no tenga una relación padre / hijo.

Agregue el evento stop propogation / event prevent default en su proveedor interno de estado:

  $stateProvider.state("outer", { url: "/outer", resolve: { test: function() { alert("Triggered state outer"); return true; } } }).state("inner", { url: "/inner", resolve: { test: function() { alert("Triggered state inner"); //$event.stopPropagation(); $event.preventDefault(); return true; } } }) 

Actualización 1: probé la demostración de Plunker y $ evento está disponible. Según doc angular también para
El objeto de evento está disponible como $ evento. DEMO Angular doc

Actualización 2: arriba funciona si presiona div externo primero, pero esa no es la solución, estoy de acuerdo. Entonces aquí hay otra solución que funciona. comprobando el cambio de estado de scope y guardando el último nombre de estado en var y comprobando si su evento interno then preventdefault;

 app.controller('MainCtrl', function($scope) { $scope.name = 'World'; var laststate = ""; $scope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) { //alert(laststate); if (laststate == "inner") { event.preventDefault(); } laststate = toState.name; }); }); 

DEMO Plunker

El problema no está en tu código de JavaScript sino en tu html

   Outer Inner  

cuando haga clic en cualquier lugar dentro de la etiqueta, se invocará el estado externo.

tu

Interior

se encuentra dentro de la etiqueta por lo que este elemento html está vinculado a ui-sref = “inner” y ui-sref = “outer”

el siguiente código debería resolver su problema

  Outer  Inner