@@ -37,6 +37,7 @@ import { UIInjector } from '../interface';
37
37
import { RawParams } from '../params/interface' ;
38
38
import { ResolvableLiteral } from '../resolve/interface' ;
39
39
import { Rejection } from './rejectFactory' ;
40
+ import { applyPairs , flattenR , uniqR } from '../common' ;
40
41
41
42
/** @hidden */
42
43
const stateSelf : ( _state : StateObject ) => StateDeclaration = prop ( 'self' ) ;
@@ -286,6 +287,87 @@ export class Transition implements IHookRegistry {
286
287
return Object . freeze ( this . _treeChanges [ pathname ] . map ( prop ( 'paramValues' ) ) . reduce ( mergeR , { } ) ) ;
287
288
}
288
289
290
+ /**
291
+ * Gets the new values of any parameters that changed during this transition.
292
+ *
293
+ * Returns any parameter values that have changed during a transition, as key/value pairs.
294
+ *
295
+ * - Any parameter values that have changed will be present on the returned object reflecting the new value.
296
+ * - Any parameters that *not* have changed will not be present on the returned object.
297
+ * - Any new parameters that weren't present in the "from" state, but are now present in the "to" state will be present on the returned object.
298
+ * - Any previous parameters that are no longer present (because the "to" state doesn't have them) will be included with a value of `undefined`.
299
+ *
300
+ * The returned object is immutable.
301
+ *
302
+ * #### Examples:
303
+ *
304
+ * Given:
305
+ * ```js
306
+ * var stateA = { name: 'stateA', url: '/stateA/:param1/param2' }
307
+ * var stateB = { name: 'stateB', url: '/stateB/:param3' }
308
+ * var stateC = { name: 'stateB.nest', url: '/nest/:param4' }
309
+ * ```
310
+ *
311
+ * #### Example 1
312
+ *
313
+ * From `/stateA/abc/def` to `/stateA/abc/xyz`
314
+ *
315
+ * ```js
316
+ * var changed = transition.paramsChanged()
317
+ * // changed is { param2: 'xyz' }
318
+ * ```
319
+ *
320
+ * The value of `param2` changed to `xyz`.
321
+ * The value of `param1` stayed the same so its value is not present.
322
+ *
323
+ * #### Example 2
324
+ *
325
+ * From `/stateA/abc/def` to `/stateB/123`
326
+ *
327
+ * ```js
328
+ * var changed = transition.paramsChanged()
329
+ * // changed is { param1: undefined, param2: undefined, param3: '123' }
330
+ * ```
331
+ *
332
+ * The value `param3` is present because it is a new param.
333
+ * Both `param1` and `param2` are no longer present so their value is undefined.
334
+ *
335
+ * #### Example 3
336
+ *
337
+ * From `/stateB/123` to `/stateB/123/nest/456`
338
+ *
339
+ * ```js
340
+ * var changed = transition.paramsChanged()
341
+ * // changed is { param4: '456' }
342
+ * ```
343
+ *
344
+ * The value `param4` is present because it is a new param.
345
+ * The value of `param3` did not change, so its value is not present.
346
+ *
347
+ * @returns an immutable object with changed parameter keys/values.
348
+ */
349
+ paramsChanged ( ) : { [ paramName : string ] : any } ;
350
+ paramsChanged < T > ( ) : T ;
351
+ paramsChanged ( ) {
352
+ const fromParams = this . params ( 'from' ) ;
353
+ const toParams = this . params ( 'to' ) ;
354
+
355
+ // All the parameters declared on both the "to" and "from" paths
356
+ const allParamDescriptors : Param [ ] = [ ]
357
+ . concat ( this . _treeChanges . to )
358
+ . concat ( this . _treeChanges . from )
359
+ . map ( pathNode => pathNode . paramSchema )
360
+ . reduce ( flattenR , [ ] )
361
+ . reduce ( uniqR , [ ] ) ;
362
+
363
+ const changedParamDescriptors = Param . changed ( allParamDescriptors , fromParams , toParams ) ;
364
+
365
+ return changedParamDescriptors . reduce ( ( changedValues , descriptor ) => {
366
+ changedValues [ descriptor . id ] = toParams [ descriptor . id ] ;
367
+ return changedValues ;
368
+ } , { } ) ;
369
+ }
370
+
289
371
/**
290
372
* Creates a [[UIInjector]] Dependency Injector
291
373
*
0 commit comments