我创建了一对指令,一个对
HTML
<div>
<h3>Both</h3>
<img
sGetSrc="//via.placeholder.com/120x60?text=Good"
sFallback="//via.placeholder.com/120x60?text=Fallback"
>
</div>
GetSrcDirective [sGetSrc]
export class GetSrcDirective {
@HostBinding('src') @Input('sGetSrc') image!: string;
}
FallbackDirective [sFallback]
export class FallbackDirective {
@HostBinding('class.no-image') hasError = false;
private originalSrc!: string;
@Input('src') set src(value: string) {
if (!value) { return; }
if (value == this.originalSrc) { return; }
this.hasError = false;
this.originalSrc = value;
}
@Input() sFallback!: string;
@HostBinding('src') get currentSrc(): string {
if (this.hasError) {
return this.sFallback;
} else {
return this.originalSrc;
}
}
@HostListener('error')
failure() {
this.hasError = true;
}
}
从此代码中,我希望它将src
设置为GetSrcDirective指令的某个值,然后FallbackDirective应该在发生错误的情况下更改img [src]。
但是现在以某种方式将src设置为null,确切地说,我已经进行了一些调试,并且按休整的顺序进行了这些操作,从而导致将src
设置为null:
sGetSrc
设置为image
src
设置为image
Input('src')
设置为image
src
设置为value
sGetSrc
设置为 null
null
我是否错过任何行为,还是这个角度误差?
Stackblitz:https://stackblitz.com/edit/angular-pvqy4g
答案 0 :(得分:0)
我已经与Angular团队交谈,他们非常友好地回应:
总的来说,我不相信这段代码会按您的预期工作。在Angular中,一个指令无法将输入设置为另一指令-例如,如果元素具有两个指令,并且其中一个指令具有
@HostBinding('[src]')
,则不会导致另一指令的@Input('src')
被更新。唯一可以更新@Input
的东西是模板中的绑定表达式。
有了这一点,我意识到,解决它的简单方法就是让指令彼此通信。
GetSrcDirective [sGetSrc]
export class GetSrcDirective {
@HostBinding('src') srcBinding!: string;
@Input('sGetSrc') set image(source: string) {
this.srcBinding = source
if (this.fallbackDirective) {
this.fallbackDirective.setSource(source);
}
}
constructor(
@Host() @Optional() fallbackDirective: FallbackDirective,
) { }
}
FallbackDirective [sFallback]
export class FallbackDirective {
@HostBinding('class.no-image') hasError = false;
private originalSrc!: string;
@Input('src') set src(value: string) {
if (!value) { return; }
this.setSource(value);
}
@Input() sFallback!: string;
@HostBinding('src') get currentSrc(): string {
if (this.hasError) {
return this.sFallback;
} else {
return this.originalSrc;
}
}
setSource(source: string) {
if (value == this.originalSrc) { return; }
this.hasError = false;
this.originalSrc = value;
}
@HostListener('error')
failure() {
this.hasError = true;
}
}
重要的部分是@Host() @Optional() fallbackDirective: FallbackDirective
,它说,FallbackDirective
位于同一元素上(如果存在)。然后,如果我们有它,我们将直接对其进行更新,从而解决问题。这也是Angular希望我们这样做的方式。