angular - 是否可以将后备模板 ref 添加到指令中?
问题描述
在 Angular 8 中,我使用指令来读取存储中的值,而不是根据值呈现 div:
指令:
@Directive({
selector: '[appOperator]'
})
export class OperatorDirective implements OnInit, OnDestroy {
private isOperator = false;
private subscription: Subscription;
constructor(private elementRef: ElementRef,
private viewContainer: ViewContainerRef,
private templateRef: TemplateRef<any>,
private store$: Store<RootStoreState.IAppState>) { }
ngOnInit() {
this.subscription = this.store$.pipe(select(AuthStoreSelectors.isOperator)).subscribe((isOperator) => {
this.isOperator = isOperator;
this.setElementOperation();
});
}
setElementOperation(): void {
if (this.isOperator) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
用例:
<app-name-input
class="header_name"
[name]="waypoint.name"
(nameChange)="applyRename(waypoint, $event)"
*appOperator
></app-name-input>
我想要某种后备模板,以防原始内容被隐藏。所以我试图在这种情况下显示的指令中添加一个模板回退:
我补充说:
@Input() fallBackTemplateRef: TemplateRef<any>;
setElementOperation(): void {
if (this.isOperator) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
if(this.fallBackTemplateRef) {
this.viewContainer.createEmbeddedView(this.fallBackTemplateRef);
}
}
}
我正在尝试按如下方式使用它
<ng-template #myTemplate let-waypoint="waypoint">
<div class="header_name">{{waypoint.name}}</div>
</ng-template>
<app-name-input
class="header_name"
[name]="waypoint.name"
(nameChange)="applyRename(waypoint, $event)"
appOperator
*appOperator
fallBackTemplateRef="myTemplate"
></app-name-input>
我面临的问题是这个编译但在应用程序中不起作用,fallBackTemplateRef
总是未定义,我什么也画不出来
是否有可能实现我想要做的事情?我错过了什么?
解决方案
在您的版本中,您没有绑定到fallbackTemplateRef
. 并且尝试使用该[fallbackTemplateRef]
语法将尝试绑定到组件上的输入属性。
要绑定到结构指令上的其他属性,您可以*ngFor
举个例子。
*ngFor="let item of collection;trackBy: trackByFn"
在源代码中,这是通过创建一个以指令选择器为前缀的输入属性来实现的:
@Input() set ngForTrackBy(fn: TrackByFn) {
this._trackByFn = fn;
}
解决方案
演示:https ://stackblitz.com/edit/router-template-vm1hsv
我已修改您的指令以采用以下样式的附加输入属性*ngForTrackBy
:
import { Directive, OnInit, OnDestroy, ElementRef, ViewContainerRef, TemplateRef, Input } from '@angular/core';
import { Subject, interval } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Directive({
selector: '[appOperator]'
})
export class OperatorDirective implements OnInit, OnDestroy {
constructor(private elementRef: ElementRef,
private viewContainer: ViewContainerRef,
private templateRef: TemplateRef<any>
) {
}
// dummy default input
@Input('appOperator') dummy: string;
@Input('appOperatorFallback') fallback: TemplateRef<any>;
private isOperator = false;
private destroyed: Subject<void> = new Subject<void>();
ngOnInit() {
interval(1000).pipe(
takeUntil(this.destroyed)
).subscribe(() => {
this.isOperator = !this.isOperator;
this.setElementOperation();
});
this.setElementOperation();
}
setElementOperation(): void {
this.viewContainer.clear();
if (this.isOperator) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else if(this.fallback) {
this.viewContainer.createEmbeddedView(this.fallback);
}
}
ngOnDestroy() {
this.destroyed.next();
this.destroyed.complete();
}
}
我使用了一个 rxjsinterval
来创建一个工作演示。你可以用你的 observable 替换它。
然后在 html 中使用,如下所示:
<ng-template #myfallback>
<div>
FALLBACK
</div>
</ng-template>
<other *appOperator="'';fallback:myfallback">
</other>
<other>
其他组件在哪里。
细分'';fallback:myfallback
是这样的:
''
- 这是@Input('appOperator')
虚拟输入属性的输入。它可以是除了空白之外的任何东西。我选择了一个空字符串,但它也可能是一个未声明的变量:_;fallback:myfallback
;
- 输入属性分隔符fallback:myfallback
正在将模板传递#myfallback
给@Input('appOperatorFallback') fallback: TemplateRef<any>;
属性
我的问题是这*appLoading="'';fallback:fallback"
很难看。我选择将默认输入保留为虚拟输入,因为考虑到后备不是操作员指令的主要输入值,这没有任何意义。
在我的研究中,我找不到一种方法来指定额外的输入,而不在那个初始位置指定一些东西。
如果您只有一个输入并且不喜欢我不情愿地选择的语法,您总是可以将后备作为主要输入传递:
@Input('appOperator') fallback: TemplateRef<any>;
然后它只是像这样使用它的一个例子:
*appOperator="myfallback"
对我来说,这有一些认知失调,但至少它很漂亮:)
推荐阅读
- php - number_format() 宽度为 100%
- python-3.x - Matplotlib xticks 隐藏图形光标信息
- laravel - 如何在 Laravel+Vue 应用中使用本地化
- python - 如何以类似于 Python 和 Pyenv 的方式从 shell 管理多个版本的 R
- android - Xamarin.Android 上是否有任何应用事件?
- postgresql - PostgreSQL (pg_hba.conf / postgresql.conf) 与服务器的连接丢失。尝试重置:失败
- python - Python - 如何在遍历字典列表时处理丢失的键?
- python - CS50 DNA: STR counter only works most of the time
- r - Reading Multiple CSV files and perform a logistic regression for all those files separately
- javascript - 如何检查Jquery中的重复项