@@ -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,9 @@ 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
+ *
177
+ * When the app state is "app.user" (or any children states), and contains the state parameter "user" with value "bilbobaggins",
168
178
* the resulting HTML will appear as (note the 'active' class):
169
179
* <pre>
170
180
* <ul>
@@ -173,10 +183,10 @@ function $StateRefDirective($state, $timeout) {
173
183
* </li>
174
184
* </ul>
175
185
* </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
- *
186
+ *
187
+ * The class name is interpolated **once** during the directives link time (any further changes to the
188
+ * interpolated value are ignored).
189
+ *
180
190
* Multiple classes may be specified in a space-separated format:
181
191
* <pre>
182
192
* <ul>
@@ -186,18 +196,36 @@ function $StateRefDirective($state, $timeout) {
186
196
* </ul>
187
197
* </pre>
188
198
*/
189
- $StateActiveDirective . $inject = [ '$state' , '$stateParams' , '$interpolate' ] ;
190
- function $StateActiveDirective ( $state , $stateParams , $interpolate ) {
191
- return {
199
+
200
+ /**
201
+ * @ngdoc directive
202
+ * @name ui.router.state.directive:ui-sref-active-eq
203
+ *
204
+ * @requires ui.router.state.$state
205
+ * @requires ui.router.state.$stateParams
206
+ * @requires $interpolate
207
+ *
208
+ * @restrict A
209
+ *
210
+ * @description
211
+ * The same as {@link ui.router.state.directive:ui-sref-active ui-sref-active} but will will only activate
212
+ * when the exact target state used in the `ui-sref` is active; no child states.
213
+ *
214
+ */
215
+ $StateRefActiveDirective . $inject = [ '$state' , '$stateParams' , '$interpolate' ] ;
216
+ function $StateRefActiveDirective ( $state , $stateParams , $interpolate ) {
217
+ return {
192
218
restrict : "A" ,
193
- controller : [ '$scope' , '$element' , '$attrs' , function ( $scope , $element , $attrs ) {
219
+ controller : [ '$scope' , '$element' , '$attrs' , function ( $scope , $element , $attrs ) {
194
220
var state , params , activeClass ;
195
221
196
222
// There probably isn't much point in $observing this
197
- activeClass = $interpolate ( $attrs . uiSrefActive || '' , false ) ( $scope ) ;
223
+ // uiSrefActive and uiSrefActiveEq share the same directive object with some
224
+ // slight difference in logic routing
225
+ activeClass = $interpolate ( $attrs . uiSrefActiveEq || $attrs . uiSrefActive || '' , false ) ( $scope ) ;
198
226
199
- // Allow uiSref to communicate with uiSrefActive
200
- this . $$setStateInfo = function ( newState , newParams ) {
227
+ // Allow uiSref to communicate with uiSrefActive[Equals]
228
+ this . $$setStateInfo = function ( newState , newParams ) {
201
229
state = $state . get ( newState , stateContext ( $element ) ) ;
202
230
params = newParams ;
203
231
update ( ) ;
@@ -207,13 +235,21 @@ function $StateActiveDirective($state, $stateParams, $interpolate) {
207
235
208
236
// Update route state
209
237
function update ( ) {
210
- if ( $state . $current . self === state && matchesParams ( ) ) {
238
+ if ( isMatch ( ) ) {
211
239
$element . addClass ( activeClass ) ;
212
240
} else {
213
241
$element . removeClass ( activeClass ) ;
214
242
}
215
243
}
216
244
245
+ function isMatch ( ) {
246
+ if ( typeof $attrs . uiSrefActiveEq !== 'undefined' ) {
247
+ return $state . $current . self === state && matchesParams ( ) ;
248
+ } else {
249
+ return $state . includes ( state . name ) && matchesParams ( ) ;
250
+ }
251
+ }
252
+
217
253
function matchesParams ( ) {
218
254
return ! params || equalForKeys ( params , $stateParams ) ;
219
255
}
@@ -223,4 +259,5 @@ function $StateActiveDirective($state, $stateParams, $interpolate) {
223
259
224
260
angular . module ( 'ui.router.state' )
225
261
. directive ( 'uiSref' , $StateRefDirective )
226
- . directive ( 'uiSrefActive' , $StateActiveDirective ) ;
262
+ . directive ( 'uiSrefActive' , $StateRefActiveDirective )
263
+ . directive ( 'uiSrefActiveEq' , $StateRefActiveDirective ) ;
0 commit comments