@@ -80,7 +80,7 @@ function $StateRefDirective($state, $timeout) {
80
80
81
81
return {
82
82
restrict : 'A' ,
83
- require : '?^uiSrefActive' ,
83
+ require : [ '?^uiSrefActive' , '?^uiSrefActiveEq' ] ,
84
84
link : function ( scope , element , attrs , uiSrefActive ) {
85
85
var ref = parseStateRef ( attrs . uiSref ) ;
86
86
var params = null , url = null , base = stateContext ( element ) || $state . $current ;
@@ -103,8 +103,9 @@ function $StateRefDirective($state, $timeout) {
103
103
104
104
var newHref = $state . href ( ref . state , params , options ) ;
105
105
106
- if ( uiSrefActive ) {
107
- uiSrefActive . $$setStateInfo ( ref . state , params ) ;
106
+ var activeDirective = uiSrefActive [ 1 ] || uiSrefActive [ 0 ] ;
107
+ if ( activeDirective ) {
108
+ activeDirective . $$setStateInfo ( ref . state , params ) ;
108
109
}
109
110
if ( ! newHref ) {
110
111
nav = false ;
@@ -148,12 +149,20 @@ function $StateRefDirective($state, $timeout) {
148
149
* @restrict A
149
150
*
150
151
* @description
151
- * A directive working alongside ui-sref to add classes to an element when the
152
+ * A directive working alongside ui-sref to add classes to an element when the
152
153
* related ui-sref directive's state is active, and removing them when it is inactive.
153
- * The primary use-case is to simplify the special appearance of navigation menus
154
+ * The primary use-case is to simplify the special appearance of navigation menus
154
155
* relying on `ui-sref`, by having the "active" state's menu button appear different,
155
156
* distinguishing it from the inactive menu items.
156
157
*
158
+ * ui-sref-active can live on the same element as ui-sref or on a parent element. The first
159
+ * ui-sref-active found at the same level or above the ui-sref will be used.
160
+ *
161
+ * Will activate when the ui-sref's target state or any child state is active. If you
162
+ * need to activate only when the ui-sref target state is active and *not* any of
163
+ * it's children, then you will use
164
+ * {@link ui.router.state.directive:ui-sref-active-eq ui-sref-active-eq}
165
+ *
157
166
* @example
158
167
* Given the following template:
159
168
* <pre>
@@ -163,8 +172,8 @@ function $StateRefDirective($state, $timeout) {
163
172
* </li>
164
173
* </ul>
165
174
* </pre>
166
- *
167
- * When the app state is "app.user", and contains the state parameter "user" with value "bilbobaggins",
175
+ *
176
+ * When the app state is "app.user" (or any children states) , and contains the state parameter "user" with value "bilbobaggins",
168
177
* the resulting HTML will appear as (note the 'active' class):
169
178
* <pre>
170
179
* <ul>
@@ -173,10 +182,10 @@ function $StateRefDirective($state, $timeout) {
173
182
* </li>
174
183
* </ul>
175
184
* </pre>
176
- *
177
- * The class name is interpolated **once** during the directives link time (any further changes to the
178
- * interpolated value are ignored).
179
- *
185
+ *
186
+ * The class name is interpolated **once** during the directives link time (any further changes to the
187
+ * interpolated value are ignored).
188
+ *
180
189
* Multiple classes may be specified in a space-separated format:
181
190
* <pre>
182
191
* <ul>
@@ -186,18 +195,36 @@ function $StateRefDirective($state, $timeout) {
186
195
* </ul>
187
196
* </pre>
188
197
*/
189
- $StateActiveDirective . $inject = [ '$state' , '$stateParams' , '$interpolate' ] ;
190
- function $StateActiveDirective ( $state , $stateParams , $interpolate ) {
191
- return {
198
+
199
+ /**
200
+ * @ngdoc directive
201
+ * @name ui.router.state.directive:ui-sref-active-eq
202
+ *
203
+ * @requires ui.router.state.$state
204
+ * @requires ui.router.state.$stateParams
205
+ * @requires $interpolate
206
+ *
207
+ * @restrict A
208
+ *
209
+ * @description
210
+ * The same as {@link ui.router.state.directive:ui-sref-active ui-sref-active} but will will only activate
211
+ * when the exact target state used in the `ui-sref` is active; no child states.
212
+ *
213
+ */
214
+ $StateRefActiveDirective . $inject = [ '$state' , '$stateParams' , '$interpolate' ] ;
215
+ function $StateRefActiveDirective ( $state , $stateParams , $interpolate ) {
216
+ return {
192
217
restrict : "A" ,
193
- controller : [ '$scope' , '$element' , '$attrs' , function ( $scope , $element , $attrs ) {
218
+ controller : [ '$scope' , '$element' , '$attrs' , function ( $scope , $element , $attrs ) {
194
219
var state , params , activeClass ;
195
220
196
221
// There probably isn't much point in $observing this
197
- activeClass = $interpolate ( $attrs . uiSrefActive || '' , false ) ( $scope ) ;
222
+ // uiSrefActive and uiSrefActiveEq share the same directive object with some
223
+ // slight difference in logic routing
224
+ activeClass = $interpolate ( $attrs . uiSrefActiveEq || $attrs . uiSrefActive || '' , false ) ( $scope ) ;
198
225
199
- // Allow uiSref to communicate with uiSrefActive
200
- this . $$setStateInfo = function ( newState , newParams ) {
226
+ // Allow uiSref to communicate with uiSrefActive[Equals]
227
+ this . $$setStateInfo = function ( newState , newParams ) {
201
228
state = $state . get ( newState , stateContext ( $element ) ) ;
202
229
params = newParams ;
203
230
update ( ) ;
@@ -207,13 +234,21 @@ function $StateActiveDirective($state, $stateParams, $interpolate) {
207
234
208
235
// Update route state
209
236
function update ( ) {
210
- if ( $state . $current . self === state && matchesParams ( ) ) {
237
+ if ( isMatch ( ) ) {
211
238
$element . addClass ( activeClass ) ;
212
239
} else {
213
240
$element . removeClass ( activeClass ) ;
214
241
}
215
242
}
216
243
244
+ function isMatch ( ) {
245
+ if ( typeof $attrs . uiSrefActiveEq !== 'undefined' ) {
246
+ return $state . $current . self === state && matchesParams ( ) ;
247
+ } else {
248
+ return $state . includes ( state . name ) && matchesParams ( ) ;
249
+ }
250
+ }
251
+
217
252
function matchesParams ( ) {
218
253
return ! params || equalForKeys ( params , $stateParams ) ;
219
254
}
@@ -223,4 +258,5 @@ function $StateActiveDirective($state, $stateParams, $interpolate) {
223
258
224
259
angular . module ( 'ui.router.state' )
225
260
. directive ( 'uiSref' , $StateRefDirective )
226
- . directive ( 'uiSrefActive' , $StateActiveDirective ) ;
261
+ . directive ( 'uiSrefActive' , $StateRefActiveDirective )
262
+ . directive ( 'uiSrefActiveEq' , $StateRefActiveDirective ) ;
0 commit comments