2014-03-05 20 views
17

假設我有嵌套的DOM,並且每個都有ui-sref不同的angular-ui-router狀態。我想點擊外部只提醒外部並點擊內部只提醒內部。目前如果我點擊內部,它會警告外部和內部狀態。防止在嵌套時調用父親ui-sref

HTML:

<!DOCTYPE html> 
<html ng-app="plunker"> 

    <head> 
    <meta charset="utf-8" /> 
    <title>AngularJS Plunker</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="[email protected]" src="http://code.angularjs.org/1.2.13/angular.js" data-semver="1.2.13"></script> 
    <script data-require="[email protected]" data-semver="0.2.8" src="http://angular-ui.github.io/ui-router/release/angular-ui-router.js"></script> 
    <script src="app.js"></script> 
    </head> 

    <body ng-controller="MainCtrl"> 
    <a ui-sref="outer" style="width:300px;height:300px;background:yellow;"> 
     Outer 
      <span ui-sref="inner" style="width:100px;height:100px;background:red;">Inner</span> 
    </a> 
    </body> 

</html> 

的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) { 
}); 

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

問題

  1. 如何防止內部觸發外部狀態?

  2. 我應該爲內部DOM實現某種stopImmediatePropagation,所以它不會觸發父DOM的ui-sref

  3. 有替代品嗎?也許手動使用$state.go

更新1:

我不能因要求更改HTML。這只是一個簡化版本,因爲在我的代碼中,外部元素非常大,包含其他元素。

回答

6

這工作

<a ui-sref="outer" style="width:300px;height:300px;background:yellow;"> 
    Outer 
     <span ui-sref="inner" style="width:100px;height:100px;background:red;" ng-click="$event.stopPropagation()">Inner</span> 
</a> 

我不知道,你可以在同一個元素添加ng-click="$event.stopPropagation()"ui-sref

+1

它的工作原理,但我似乎得到整個頁面重新加載,這可能不是所需的行爲......當然不適合我。 – Lewis

+0

ui-sref更新a標籤的href項,它對click事件沒有影響。和jQuery一樣,你可以使用$('a')。attr('href','http://example.com').on('click',(e)=> {/ * something */})''' – itanex

0

的問題不在於你的JavaScript代碼,但你的HTML

<a ui-sref="outer" style="width:300px;height:300px;background:yellow;"> 
     Outer 
      <span ui-sref="inner" style="width:100px;height:100px;background:red;">Inner</span> 
    </a> 

當您單擊標籤內的任何地方,外狀態將被調用。

位於內部標記,以便此html元素綁定到兩個UI-SREF = 「內」 和UI-SREF = 「外」

下面的代碼應解決您問題

<a ui-sref="outer" style="width:300px;height:300px;background:yellow;"> 
     Outer 

    </a> 

<span ui-sref="inner" style="width:100px;height:100px;background:red;">Inner</span> 
+0

請看看我的'更新1'。我知道改變HTML來解決這個問題,但這不是我的範圍。 –

0

我應該實現某種stopImmediatePropagation的內部DOM,所以它不會觸發父母DOM的ui-sref

是的,正好。

或者,您可能可以重新排列您的HTML,以便沒有父/子關係。

0

添加事件停止傳播史/事件阻止在默認烏爾內stateprovider:

$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; 
    } 
    } 
}) 

更新1:我試着plunker演示和$事件是可用的。根據角度文檔也爲
事件對象可用作$事件。 DEMOAngular doc

更新2:上面的作品,如果你先按外部div,但這不是rt解決方案我同意。所以這裏是另一種解決方案。檢查作用域的statechangestart並在var中保存最後的狀態名稱並檢查其內部的當前事件是否爲默認;

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

+0

它不起作用。如何在'resolve'中訪問'$ event'? –

+0

@HP。我更新了答案。看看它的幫助。 – Neha

+0

我點了內部,它提示了內在的一個和外部,因此不符合要求 –

34

使用本...

<a ui-sref="outer" style="width:300px;height:300px;background:yellow;"> 
Outer 
    <span ui-sref="inner" style="width:100px;height:100px;background:red;" 
    ng-click="$event.stopPropagation()">Inner</span> 
</a> 
+3

你的功夫很強大。 –

+0

我有一個類似的情況,但不是內部鏈接,我不得不調用一個函數。僅使用$ event.stopPropagation()仍導致導航。添加$ event.preventDefault()修復了這個問題。我從http://stackoverflow.com/a/25636705/2487876 – CapK

+0

得到了很大的啓發。榮譽給你! – SolidSmile

1

爲了完全不同的目的,我有一個stopEvent指令,只是等待用於嵌套的ui-sref目的。

<a ui-sref="outer"> 
    Outer 
    <span ui-sref="inner" stop-event>Inner</span> 
</a> 

這是指令

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