输入更改时指令不会触发
Directive doesn't trigger when input changes
我正在实施一个指令,该指令将一种语言(或一组语言)作为输入并将 class 添加到添加指令的 DOM 元素。
@Directive({
selector: '[appRtlView]'
})
export class RTLViewDirective implements OnInit, OnChanges {
@Input('appRtlView') inputLanguage: string | string[];
constructor(private el: ElementRef) {}
ngOnInit() {
this.handleRtl();
}
private handleRtl() {
if (this.inputLanguage) {
let languageList = null;
if (!Array.isArray(this.inputLanguage)) {
languageList = [this.inputLanguage];
} else {
languageList = this.inputLanguage;
}
// both conditions do stuff with this.el.nativeElement.classList
if (languageList.includes('ar')) {
this.addRtl();
} else {
this.removeIfRtlExists();
}
}
}
}
下面是我使用指令的地方。 "languagesInView" 是一个字符串列表,使用 @Input() 在使用此指令的组件中摄取 ...
<div *ngIf="concept">
<div class="concept-header" [appRtlView]="languagesInView">
...
</div>
</div>
我希望当传递到组件的 languagesInView 输入发生变化时,我传递给模板中 [appRtlView] 的值也会发生变化。
(通过使用插值 {{ languagesInView }} 将值打印到屏幕,我可以看到该值实际上发生了变化)
在 RTLView 指令中,如果我使用 ngOnInit,则不会获取对 "inputLanguage" 字段的更改。
为了克服这个问题,我在指令中使用了 ngOnChanges(实现 OnChanges 就是我想要的):
// ngOnInit added because Angular doesn't accept a directive without an OnInit implementation
ngOnInit() {}
ngOnChanges(change: SimpleChanges) {
// TODO: A check to see if the input value has changed or not would help performance
this.handleRtl();
}
我无法将 changeDetectionStrategy 添加到指令初始化中,这让我认为指令通常不应该实现 OnChanges。我的在线搜索没有多大帮助。
在 Angular 指令中使用 ngOnChanges 运行 是错误的吗?
谢谢
ngOnChanges
仅在输入更改来自 <component [someInput]="aValue">
.
等模板绑定时运行
有几种方法可以解决这个问题。
- 直接进行
ngOnChanges
会做的更改。
- 使用
ChangeDetectorRef
手动触发更改检测。
我想我的答案来自 lifecycle hooks documentation。
我的问题归结为我是否可以 use/should 在指令中使用 ngOnChanges。粗体线正是我所需要的。
生命周期挂钩
组件的生命周期由 Angular 管理。
Angular 创建它,渲染它,创建并渲染它的子级,当它的数据绑定属性改变时检查它,并在从 DOM.[=11= 中删除它之前销毁它]
Angular 提供生命周期挂钩,可让您了解这些关键的生活时刻以及在这些时刻发生时采取行动的能力。
指令具有相同的生命周期钩子集。
感谢所有回复的人。
我正在实施一个指令,该指令将一种语言(或一组语言)作为输入并将 class 添加到添加指令的 DOM 元素。
@Directive({
selector: '[appRtlView]'
})
export class RTLViewDirective implements OnInit, OnChanges {
@Input('appRtlView') inputLanguage: string | string[];
constructor(private el: ElementRef) {}
ngOnInit() {
this.handleRtl();
}
private handleRtl() {
if (this.inputLanguage) {
let languageList = null;
if (!Array.isArray(this.inputLanguage)) {
languageList = [this.inputLanguage];
} else {
languageList = this.inputLanguage;
}
// both conditions do stuff with this.el.nativeElement.classList
if (languageList.includes('ar')) {
this.addRtl();
} else {
this.removeIfRtlExists();
}
}
}
}
下面是我使用指令的地方。 "languagesInView" 是一个字符串列表,使用 @Input() 在使用此指令的组件中摄取 ...
<div *ngIf="concept">
<div class="concept-header" [appRtlView]="languagesInView">
...
</div>
</div>
我希望当传递到组件的 languagesInView 输入发生变化时,我传递给模板中 [appRtlView] 的值也会发生变化。 (通过使用插值 {{ languagesInView }} 将值打印到屏幕,我可以看到该值实际上发生了变化)
在 RTLView 指令中,如果我使用 ngOnInit,则不会获取对 "inputLanguage" 字段的更改。
为了克服这个问题,我在指令中使用了 ngOnChanges(实现 OnChanges 就是我想要的):
// ngOnInit added because Angular doesn't accept a directive without an OnInit implementation
ngOnInit() {}
ngOnChanges(change: SimpleChanges) {
// TODO: A check to see if the input value has changed or not would help performance
this.handleRtl();
}
我无法将 changeDetectionStrategy 添加到指令初始化中,这让我认为指令通常不应该实现 OnChanges。我的在线搜索没有多大帮助。
在 Angular 指令中使用 ngOnChanges 运行 是错误的吗?
谢谢
ngOnChanges
仅在输入更改来自 <component [someInput]="aValue">
.
有几种方法可以解决这个问题。
- 直接进行
ngOnChanges
会做的更改。 - 使用
ChangeDetectorRef
手动触发更改检测。
我想我的答案来自 lifecycle hooks documentation。 我的问题归结为我是否可以 use/should 在指令中使用 ngOnChanges。粗体线正是我所需要的。
生命周期挂钩
组件的生命周期由 Angular 管理。
Angular 创建它,渲染它,创建并渲染它的子级,当它的数据绑定属性改变时检查它,并在从 DOM.[=11= 中删除它之前销毁它]
Angular 提供生命周期挂钩,可让您了解这些关键的生活时刻以及在这些时刻发生时采取行动的能力。
指令具有相同的生命周期钩子集。
感谢所有回复的人。