我正在开发一个 Angular 指令来检测(并删除)列表中的一个空项目*ngFor
。
我不是添加X
会触发删除的按钮(每个项目),而是更多基于内容的方法:如果用户删除 - 完全或只是删除 - 一个项目的一些关键字段,它将很快不存在当用户关注文档的另一部分时。
我设法做到了(令我惊讶的是,这并不困难)。我将在这里强调关键方面:
使用指令
模板
<div *ngFor="let item of data; index as i"
[appInPlaceDelete]="isEmpty"
(delete)="onDelete(i)"
>
零件
onDelete(i: number) {
// code to erase ith item
}
private isEmpty(item): boolean {
// logic to answer if item is empty or not
}
执行
@Directive({
selector: '[appInPlaceDelete]'
})
export class InPlaceDeleteDirective<T> implements OnInit, DoCheck {
@Input() appInPlaceDelete: (t: T) => boolean;
@Output() delete: EventEmitter<undefined> = new EventEmitter();
// ...
private $implicit: T;
private focusstream = new Subject<string>();
constructor(private containerRef: ViewContainerRef) {
}
ngOnInit() {
const context: NgForOfContext<T> = this.containerRef['_view'].context;
this.$implicit = context.$implicit
// code forwarding 'focusstream' to 'delete' output
}
// code that gives visual indication that the item will be deleted
// ...
// a bunch of @HostListeners feeding the focusstream
// ...
}
现在,我对我所做的非常满意,除了那一行:
const context: NgForOfContext<T> = this.containerRef['_view'].context;
因为访问该_view
属性不是平台可移植的(也许该属性仅存在于 中platformBrowserDynamic
)。
问题来了:
- 有什么方法可以捕获
context
平台独立的方式吗?
NgForOf
如其源代码所示,将这个上下文独立地填充到平台上。也许有(或应该有)一种可移植地检索该上下文的方法。我知道,开发人员(我)仍然有责任知道该上下文包含什么(它的类型)。等等,这是下一个问题。
- 我可以更严格地只在主机
selector
内部进行挂钩吗?*ngFor
对于这个我知道我们应该记住,角度将原始模板转换为:
<ng-template ngFor let-item [ngForOf]="data" let-i="index">
<div
[appInPlaceDelete]="isEmpty"
(delete)="onDelete(i)"
>
</ng-template>
因此,divs
该指令实际挂钩的是由NgForOf
指令动态创建的嵌入式视图。
我想知道是否有某种方法可以强制执行此操作(我尝试selector: '[ngFor] > [appInPlaceDelete]'
无济于事)。
- 有解决方法吗?
输出清楚地使用delete
了上下文变量i
(指令本身一无所知i
;它只是通过通道发出一个事件delete
)。
尽管我[appInPlaceDelete]="isEmpty(item)"
事先知道它会绑定false
到appInPlaceDelete
.
我还尝试[appInPlaceDelete]="() => isEmpty(item)"
并...="function() { return isEmpty(item); }"
期望 angular 会创建一个闭包抓取item
(and isEmpty
) 并传递该闭包。也没有成功。
虽然有点难看,但这比非便携式指令要好。
- 如果没有其他方法可以肯定地回答第一个问题,并且在第三个问题中也没有解决方法,我如何才能至少涵盖最常见的平台?
虽然不可取,但也许我可以有一些方法来确定我的指令在哪个平台上运行并context
具体访问。
在这件事上,我不得不承认我不知道如何使用(更不用说调试)除了platformBrowserDynamic
.
- 如果您到目前为止,还有其他完全不同的方法吗?
这篇文章的前两段描述了我在这里想要完成的事情。其他一切都只是我的解决方案(以及它带来的问题)。
也许有一种完全不同的方式来做到这一点。也许有人已经做了/打包/发布了更好的解决方案。