Angular 2 动画 - 布尔触发器?

Angular 2 Animation - boolean trigger?

我正在尝试触发绑定到布尔值的转换 属性,但这似乎没有触发。

这是我的动画触发器的简化版本

trigger(
  'trueFalseAnimation', [
    transition('* => true', [
      style({backgroundColor: '#00f7ad'}),
      animate('2500ms', style({backgroundColor: '#fff'}))
    ]),
    transition('* => false', [
      style({backgroundColor: '#ff0000'}),
      animate('2500ms', style({backgroundColor: '#fff'}))
    ])
  ]
)

HTML:

<div [@trueFalseAnimation]="model.someProperty">Content here</div>

测试:

ngOnInit() {

    setTimeout(() => {
        this.model.someProperty = true;
        setTimeOut(() => {
            this.model.someProperty = false;
        }, 5000);    
    }, 1000)
}

someProperty 改变时,触发永远不会发生。

作为快速测试,我将触发器更改为使用字符串并且它有效

trigger(
      'trueFalseAnimation', [
        transition('* => Success', [
          style({backgroundColor: '#00f7ad'}),
          animate('2500ms', style({backgroundColor: '#fff'}))
        ]),
        transition('* => Failed', [
          style({backgroundColor: '#ff0000'}),
          animate('2500ms', style({backgroundColor: '#fff'}))
        ])
      ]
    )

测试:

ngOnInit() {

    setTimeout(() => {
        this.model.someProperty = "Success";
        setTimeOut(() => {
            this.model.someProperty = "Failed";
        }, 5000);    
    }, 1000)
}

第二个例子工作得很好

我的问题是

  1. 是否支持布尔值作为触发器?
  2. 如果#1 是,我是什么 做错了吗?

我遇到了同样的问题。不确定是否支持布尔值作为触发器,但我发现的解决方法是定义一个字符串 属性 和 getter 到 return 布尔值作为字符串。像这样:

get somePropertyStr():string {
    return this.someProperty.toString();
}

然后你应该将你的动画绑定到 somePropertyStr 属性.

再一次,这是一个丑陋的解决方法,最好的办法是使用布尔值。

  1. 好像不是。我看到一个问题 (12337) 已经被提出 为此,目前还没有更新。
  2. 另一种选择是使用 1 和 0 而不是 true 和 false。

参见plunker from here

trigger('isVisibleChanged', [
      state('true' , style({ opacity: 1, transform: 'scale(1.0)' })),
      state('false', style({ opacity: 0, transform: 'scale(0.0)'  })),
      transition('1 => 0', animate('300ms')),
      transition('0 => 1', animate('900ms'))
])

编辑:正如其他一些答案所暗示的,行为已经改变。如果您感兴趣,这里是相关的 Angular 源代码:

const TRUE_BOOLEAN_VALUES = new Set<string>(['true', '1']);
const FALSE_BOOLEAN_VALUES = new Set<string>(['false', '0']);

function makeLambdaFromStates(lhs: string, rhs: string): TransitionMatcherFn {
  const LHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(lhs) || FALSE_BOOLEAN_VALUES.has(lhs);
  const RHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(rhs) || FALSE_BOOLEAN_VALUES.has(rhs);

  return (fromState: any, toState: any): boolean => {
    let lhsMatch = lhs == ANY_STATE || lhs == fromState;
    let rhsMatch = rhs == ANY_STATE || rhs == toState;

    if (!lhsMatch && LHS_MATCH_BOOLEAN && typeof fromState === 'boolean') {
      lhsMatch = fromState ? TRUE_BOOLEAN_VALUES.has(lhs) : FALSE_BOOLEAN_VALUES.has(lhs);
    }
    if (!rhsMatch && RHS_MATCH_BOOLEAN && typeof toState === 'boolean') {
      rhsMatch = toState ? TRUE_BOOLEAN_VALUES.has(rhs) : FALSE_BOOLEAN_VALUES.has(rhs);
    }

    return lhsMatch && rhsMatch;
  };
}

除非您自己调试它,否则遵循起来有点棘手,但基本上要注意的重要一点是 fromStatetoState 是您的值(当有变化时)在模板中设置动画:例如。 [@animation]="animationState"

所以你可以看到他们明确允许它们是布尔值 (typeof fromState === 'boolean')。

我被抓住的原因(并找到了回到我自己的旧答案的方式)是 Angular 的 AnimationEvent 将它们定义为字符串:

  /**
   * The name of the state from which the animation is triggered.
   */
  fromState: string;
  /**
   * The name of the state in which the animation completes.
   */
  toState: string;

因此,在您的状态设置为布尔值的动画完成后(例如 true / false 而不是 'true' / 'false' 您将运行 遇到打字问题。

event.fromState的实际值可能是true所以

  • event.fromState == true 给出编译器错误('string' 和 'boolean' 没有类型重叠)
  • event.fromState == 'true' 永远不会是真的(因为值实际上是 true

因此您需要使用:

 if (<any>(event.toState) == true)

 if ((event.toState as string | boolean) == true)

旧答案:

状态被定义为字符串,因此我们需要坚持这一点。

根据您的代码,最简单但最棘手的方法是这样

<div [@trueFalseAnimation]="model.someProperty?.toString()">Content here</div>

但这很糟糕,所以这可能更好

<div [@trueFalseAnimation]="model.someProperty ? 'active' : 'inactive'">Content here</div>
<div [@trueFalseAnimation]="model.someProperty ? 'visible' : 'hidden'">Content here</div>
<div [@trueFalseAnimation]="model.someProperty ? 'up' : 'down'">Content here</div>
<div [@trueFalseAnimation]="model.someProperty ? 'left' : 'right'">Content here</div>

这里最好的建议是使用与其真正含义相对应的状态。在这种情况下,true 和 false 究竟意味着什么?

我考虑过制作一个管道来转换布尔值,但这样做的唯一好处是确保您与状态字符串保持一致。