fix(animations): make sure reuseable animation subtitutions work without default params (#16875)

This commit is contained in:
Matias Niemelä 2017-05-18 12:59:54 -07:00 committed by Jason Aden
parent 86b7bd9c8e
commit 7d9f96abf0
2 changed files with 35 additions and 13 deletions

View File

@ -454,27 +454,28 @@ export class AnimationTimelineContext {
updateOptions(options: AnimationOptions|null, skipIfExists?: boolean) { updateOptions(options: AnimationOptions|null, skipIfExists?: boolean) {
if (!options) return; if (!options) return;
// NOTE: this will get patched up when other animation methods support duration overrides
const newOptions = options as any; const newOptions = options as any;
let optionsToUpdate = this.options;
// NOTE: this will get patched up when other animation methods support duration overrides
if (newOptions.duration != null) { if (newOptions.duration != null) {
(this.options as any).duration = resolveTimingValue(newOptions.duration); (optionsToUpdate as any).duration = resolveTimingValue(newOptions.duration);
} }
if (newOptions.delay != null) { if (newOptions.delay != null) {
this.options.delay = resolveTimingValue(newOptions.delay); optionsToUpdate.delay = resolveTimingValue(newOptions.delay);
} }
const newParams = newOptions.params; const newParams = newOptions.params;
if (newParams) { if (newParams) {
let params: {[name: string]: any} = this.options && this.options.params !; let paramsToUpdate: {[name: string]: any} = optionsToUpdate.params !;
if (!params) { if (!paramsToUpdate) {
params = this.options.params = {}; paramsToUpdate = this.options.params = {};
} }
Object.keys(params).forEach(name => { Object.keys(newParams).forEach(name => {
const value = params[name]; if (!skipIfExists || !paramsToUpdate.hasOwnProperty(name)) {
if (!skipIfExists || !newOptions.hasOwnProperty(name)) { paramsToUpdate[name] = newParams[name];
params[name] = value;
} }
}); });
} }

View File

@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be * Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {AUTO_STYLE, AnimationMetadata, AnimationMetadataType, animate, group, keyframes, query, sequence, style, ɵStyleData} from '@angular/animations'; import {AUTO_STYLE, AnimationMetadata, AnimationMetadataType, animate, animation, group, keyframes, query, sequence, style, useAnimation, ɵStyleData} from '@angular/animations';
import {AnimationOptions} from '@angular/core/src/animation/dsl'; import {AnimationOptions} from '@angular/core/src/animation/dsl';
import {Animation} from '../../src/dsl/animation'; import {Animation} from '../../src/dsl/animation';
@ -304,10 +304,31 @@ export function main() {
}); });
describe('subtitutions', () => { describe('subtitutions', () => {
it('should allow params to be subtituted even if they are not defaulted in a reusable animation',
() => {
const myAnimation = animation([
style({left: '{{ start }}'}),
animate(1000, style({left: '{{ end }}'})),
]);
const steps = [
useAnimation(myAnimation, {params: {start: '0px', end: '100px'}}),
];
const players = invokeAnimationSequence(rootElement, steps, {});
expect(players.length).toEqual(1);
const player = players[0];
expect(player.keyframes).toEqual([
{left: '0px', offset: 0},
{left: '100px', offset: 1},
]);
});
it('should substitute in timing values', () => { it('should substitute in timing values', () => {
function makeAnimation(exp: string, values: {[key: string]: any}) { function makeAnimation(exp: string, options: {[key: string]: any}) {
const steps = [style({opacity: 0}), animate(exp, style({opacity: 1}))]; const steps = [style({opacity: 0}), animate(exp, style({opacity: 1}))];
return invokeAnimationSequence(rootElement, steps, values); return invokeAnimationSequence(rootElement, steps, options);
} }
let players = makeAnimation('{{ duration }}', buildParams({duration: '1234ms'})); let players = makeAnimation('{{ duration }}', buildParams({duration: '1234ms'}));