我有一个自定义Angular指令,需要几个输入。其目的是突出显示与指令matchTerm
相加的元素的匹配部分。它应该与预输入结果列表一起使用,以便在用户键入返回的结果时突出显示匹配的字符串。
这是整个指令:
import { Directive, Input, ElementRef, OnChanges, SimpleChanges } from '@angular/core';
import { highlightStringMatches } from './typeahead.util';
@Directive({
selector: '[hsaTypeaheadResult]',
})
export class TypeaheadResultDirective implements OnChanges {
@Input() matchTerm: string = '';
@Input() highlightMatches: boolean = true;
@Input() caseInsensitiveMatch: boolean = true;
constructor(private _element: ElementRef) {
console.log({ element: this._element });
}
ngOnChanges(changes: SimpleChanges) {
console.log({ changes });
if (changes.matchTerm && this.highlightMatches) {
this.markStringMatches(this._element);
}
}
public markStringMatches(ref: ElementRef) {
const itemString = ref.nativeElement.textContent.trim();
console.log({
itemString,
matchTerm: this.matchTerm,
highlightMatches: this.highlightMatches,
caseInsensitiveMatch: this.caseInsensitiveMatch,
});
ref.nativeElement.innerHTML =
this.highlightMatches && this.matchTerm
? highlightStringMatches(itemString, this.matchTerm, this.caseInsensitiveMatch)
: itemString;
}
}
如果执行以下操作,该指令将起作用:
<ul>
<li hsaTypeaheadResult matchTerm="res">Result 1</li>
<li hsaTypeaheadResult matchTerm="res">Result 2</li>
<li hsaTypeaheadResult matchTerm="res">Result 3</li>
</ul>
每个li
的“ Res”以粗体显示。但是,如果我执行以下任一操作,将无法正常工作:
<ul>
<li hsaTypeaheadResult matchTerm="res" *ngFor="let result of resultsArr">{{ result }}</li>
</ul>
<ul>
<li hsaTypeaheadResult matchTerm="res">{{ results[0] }}</li>
<li hsaTypeaheadResult matchTerm="res">{{ results[1] }}</li>
<li hsaTypeaheadResult matchTerm="res">{{ results[2] }}</li>
</ul>
每次在使用指令的元素的大括号中插入变量时,变量的值都不会显示在屏幕上:
即使在*ngFor
元素上也有结构性li
指令的情况下,我尝试将ngFor
放在ng-template
标记上,但是仍然没用。
您可以看到一个full example on Stackblitz here。我不确定为什么它不适用于插值。在您可以在Stackblitz项目上看到的测试中,一旦发现循环在我的应用程序中无法使用插值,并且仍然可以通过测试,就使用了ngFor
循环。
我已经在一个全新的Angular CLI项目以及一个Stackblitz中进行了尝试,并且这些项目都没有其他对它产生负面影响的依赖项。任何帮助将不胜感激。
答案 0 :(得分:0)
考虑了一段时间后,我意识到使用内插时,指令的构造函数中的ElementRef.nativeElement.textContent
为空。因此,我意识到这一定意味着我在指令中运行该函数的时间过早。为了进行测试,我使用了setTimeout
并等待了2秒钟,然后运行该函数以突出显示匹配项。当我这样做时,该指令按预期工作。
此后,仅需找到在视图准备好后运行的生命周期方法即可,AfterViewInit
可以完美地工作。指令代码如下:
import { Directive, Input, ElementRef, OnChanges, SimpleChanges, AfterViewInit } from '@angular/core';
import { highlightStringMatches } from './typeahead.util';
@Directive({
selector: '[hsaTypeaheadResult]',
})
export class TypeaheadResultDirective implements OnChanges, AfterViewInit {
@Input() matchTerm: string = '';
@Input() highlightMatches: boolean = true;
@Input() caseInsensitiveMatch: boolean = true;
constructor(private _element: ElementRef) {}
ngOnChanges(changes: SimpleChanges) {
if (changes.matchTerm && this.highlightMatches && this._element.nativeElement.textContent) {
this.markStringMatches(this._element);
}
}
ngAfterViewInit() {
if (this.matchTerm && this.highlightMatches && this._element.nativeElement.textContent) {
this.markStringMatches(this._element);
}
}
public markStringMatches(ref: ElementRef) {
const itemString = ref.nativeElement.textContent.trim();
ref.nativeElement.innerHTML =
this.highlightMatches && this.matchTerm
? highlightStringMatches(itemString, this.matchTerm, this.caseInsensitiveMatch)
: itemString;
}
}