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 是,我是什么
做错了吗?
我遇到了同样的问题。不确定是否支持布尔值作为触发器,但我发现的解决方法是定义一个字符串 属性 和 getter 到 return 布尔值作为字符串。像这样:
get somePropertyStr():string {
return this.someProperty.toString();
}
然后你应该将你的动画绑定到 somePropertyStr
属性.
再一次,这是一个丑陋的解决方法,最好的办法是使用布尔值。
- 好像不是。我看到一个问题 (12337) 已经被提出
为此,目前还没有更新。
- 另一种选择是使用 1 和 0 而不是 true 和 false。
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;
};
}
除非您自己调试它,否则遵循起来有点棘手,但基本上要注意的重要一点是 fromState
和 toState
是您的值(当有变化时)在模板中设置动画:例如。 [@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 究竟意味着什么?
我考虑过制作一个管道来转换布尔值,但这样做的唯一好处是确保您与状态字符串保持一致。
我正在尝试触发绑定到布尔值的转换 属性,但这似乎没有触发。
这是我的动画触发器的简化版本
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 是,我是什么 做错了吗?
我遇到了同样的问题。不确定是否支持布尔值作为触发器,但我发现的解决方法是定义一个字符串 属性 和 getter 到 return 布尔值作为字符串。像这样:
get somePropertyStr():string {
return this.someProperty.toString();
}
然后你应该将你的动画绑定到 somePropertyStr
属性.
再一次,这是一个丑陋的解决方法,最好的办法是使用布尔值。
- 好像不是。我看到一个问题 (12337) 已经被提出 为此,目前还没有更新。
- 另一种选择是使用 1 和 0 而不是 true 和 false。
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;
};
}
除非您自己调试它,否则遵循起来有点棘手,但基本上要注意的重要一点是 fromState
和 toState
是您的值(当有变化时)在模板中设置动画:例如。 [@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 究竟意味着什么?
我考虑过制作一个管道来转换布尔值,但这样做的唯一好处是确保您与状态字符串保持一致。