Angular2 @Input 到带有 get/set 的属性
Posted
技术标签:
【中文标题】Angular2 @Input 到带有 get/set 的属性【英文标题】:Angular2 @Input to a property with get/set 【发布时间】:2016-08-07 19:29:26 【问题描述】:我在该组件中有一个 Angular2 组件,它当前有一堆字段,在它们之前应用了 @Input() 以允许绑定到该属性,即
@Input() allowDay: boolean;
我想要做的实际上是使用 get/set 绑定到一个属性,这样我就可以在 setter 中执行一些其他逻辑,如下所示
_allowDay: boolean;
get allowDay(): boolean
return this._allowDay;
set allowDay(value: boolean)
this._allowDay = value;
this.updatePeriodTypes();
我将如何在 Angular2 中做到这一点?
根据 Thierry Templier 的建议,我将其更改为,但这会引发错误 Can't bind to 'allowDay' 因为它不是已知的本机属性:
//@Input() allowDay: boolean;
_allowDay: boolean;
get allowDay(): boolean
return this._allowDay;
@Input('allowDay') set allowDay(value: boolean)
this._allowDay = value;
this.updatePeriodTypes();
【问题讨论】:
如何以及在哪里绑定到[allowDay]="....". If the field (setter) name and the property name you want to use for binding are the same, you can omit the parameter for
@Input(...)`。
如果您按照接受的答案所示的方式使用 get set,我很想知道您是如何设置单元测试的。
无论您最终做什么,请确保在您的设置器中放置一个断点、调试语句或计数器,以确保它只按预期触发一次。我刚刚发现我的每次更改检测运行都会更新,这会导致糟糕的性能和古怪的行为。
【参考方案1】:
您可以直接在 setter 上设置@Input
,如下所述:
_allowDay: boolean;
get allowDay(): boolean
return this._allowDay;
@Input() set allowDay(value: boolean)
this._allowDay = value;
this.updatePeriodTypes();
查看此 Plunkr:https://plnkr.co/edit/6miSutgTe9sfEMCb8N4p?p=preview。
【讨论】:
我收到以下错误无法绑定到“allowDay”,因为它不是已知的本机属性。有关我将代码更改为的确切内容,请参阅更新的问题 你确定吗?这个对我有用。我添加了一个 plunkr。也许您忘记将指令添加到要使用它的组件的directives
属性中......我更新了我的答案。
这是个坏主意,因为如果您使用 setter,ngOnChanges 不会触发。
On angular Fundamentals pages
警告:setter
将不会由对通过引用传递的值的突变触发(即推送到数组,改变一个对象等)。您需要替换作为Input
传递的整个值,以便setter
再次触发。【参考方案2】:
@Paul Cavacas,我遇到了同样的问题,我通过在 getter 上方设置 Input()
装饰器来解决。
@Input('allowDays')
get in(): any
return this._allowDays;
//@Input('allowDays')
// not working
set in(val)
console.log('allowDays = '+val);
this._allowDays = val;
查看此插件:https://plnkr.co/edit/6miSutgTe9sfEMCb8N4p?p=preview
【讨论】:
这个bug让我抓狂,我终于发现你应该先定义Input()(getter或setter但输入装饰器必须先行) 这里有其他可能有帮助的参考资料 https://github.com/angular/angular/issues/5477【参考方案3】:如果您的主要兴趣是仅对 setter 实现逻辑:
import Component, Input, OnChanges, SimpleChanges from '@angular/core';
// [...]
export class MyClass implements OnChanges
@Input() allowDay: boolean;
ngOnChanges(changes: SimpleChanges): void
if(changes['allowDay'])
this.updatePeriodTypes();
如果更改了哪个输入属性无关紧要,或者您只有一个输入属性,则不需要导入SimpleChanges
。
Angular Doc: OnChanges
否则:
private _allowDay: boolean;
@Input() set allowDay(value: boolean)
this._allowDay = value;
this.updatePeriodTypes();
get allowDay(): boolean
// other logic
return this._allowDay;
【讨论】:
只是好奇,如果您只对 setter 逻辑感兴趣,那么使用 ngOnChanges 与不使用 set 属性有什么好处? “使用 ngOnChanges 与不使用 set”没有区别... ;) 开个玩笑:一个好处是,如果您的组件有多个@Input
属性并且您想在以下情况下调用例程其中任何一个都发生了变化。所以需要更少的代码。
Ups,打错字了,呵呵。但是,好吧,认为它可能有更多的相关性。谢谢你的回答:)
ngOnChanges 方法很棒!!好答案。如果设置的值不能是私有的,例如它在模板中用作绑定,_propertyName setter/private 命名约定变得不一致。 ngOnChanges 完美地解决了这个问题【参考方案4】:
在此处更新了 stackblitz 上 Angular 7.0.1 的已接受答案:https://stackblitz.com/edit/angular-inputsetter?embed=1&file=src/app/app.component.ts
directives
不再出现在组件装饰器选项中。所以我为 app 模块提供了子指令。
谢谢@thierry-templier!
【讨论】:
以上是关于Angular2 @Input 到带有 get/set 的属性的主要内容,如果未能解决你的问题,请参考以下文章