angular - 如何在 Angular 2 中使用 murri 作为指令
解决方案
这是一个使用 Angular 6/7 作为指令来使用 muuri Grid 的示例
您可以将 murri 指令分配给div
定义为myTileGrid
<div #grid class="grid" myTileGrid>
<div class="grid-item" myTileGridItem *ngFor="let tile of tiles$ | async">
</div>
</div>
下面是主要的 murri 指令类
import { Directive, ElementRef, OnDestroy, OnInit } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { debounceTime, filter } from 'rxjs/operators';
declare var Muuri: any;
@Directive({
selector: '[myTileGrid]'
})
export class MyTileGridDirective implements OnInit, OnDestroy {
layoutConfig = {
items: [],
layoutOnInit: false,
dragEnabled: true,
layout: {
fillGaps: true,
horizontal: false,
alignRight: false,
alignBottom: false,
rounding: true
},
dragStartPredicate: {
distance: 0,
delay: 0,
handle: '.tile-handle'
},
dragSortInterval: 0,
dragSortPredicate: {
threshold: 40,
action: 'swap'
}
};
layout: any;
addItemChangeSubscription: any;
private events: string[];
private items: ElementRef[];
private addItemChange = new BehaviorSubject<boolean>(false);
constructor(private elRef: ElementRef) {
this.events = [];
this.items = [];
}
ngOnInit(): void {
this.addItemChangeSubscription = this.addItemChange
.pipe(
filter(t => !!t),
debounceTime(25)
)
.subscribe(t => {
this.addItems(this.items);
this.refresh();
});
this.init(this.elRef.nativeElement, true);
}
init(grid: ElementRef, fillGaps: boolean, sortAction: string = null, dragHandle: string = null) {
if (dragHandle) {
this.layoutConfig.dragStartPredicate.handle = dragHandle;
}
if (sortAction) {
this.layoutConfig.dragSortPredicate.action = sortAction;
}
this.layoutConfig.layout.fillGaps = fillGaps;
this.layout = new Muuri(grid, this.layoutConfig);
}
private addItems(items) {
let existingItems = this.layout.getItems();
if (existingItems && existingItems.length > 0) {
this.layout.remove(existingItems, { layout: false });
}
this.layout.add(items, { layout: false });
this.items = [];
}
addItem(item: ElementRef) {
this.items.push(item);
this.addItemChange.next(true);
}
on(eventName: string, action: any) {
if (this.events.find(x => x === eventName)) {
return;
}
this.layout.on(eventName, function(item, event) {
action(item, event);
});
this.events.push(eventName);
}
destroyLayout() {
this.events.forEach(eventName => {
this.layout.off(eventName);
});
this.events = [];
this.layout.destroy();
this.layout = null;
}
refresh() {
this.layout.refreshItems();
this.layout.layout();
}
ngOnDestroy(): void {
this.destroyLayout();
if (this.addItemChangeSubscription) {
this.addItemChangeSubscription.unsubscribe();
}
}
}
然后是项目本身:
import { Directive, ElementRef, Host, OnInit } from '@angular/core';
import { MyTileGridDirective } from './my-tile-grid.directive';
@Directive({
selector: '[myTileGridItem]'
})
export class MyTileGridItemDirective implements OnInit {
constructor(@Host() private tileGrid: MyTileGridDirective, private elRef: ElementRef) {}
ngOnInit(): void {
this.tileGrid.addItem(this.elRef.nativeElement);
}
}
推荐阅读
- android - Nativescript FCM firebase 插件
- excel - VBA如何使用诸如偏移之类的东西来更改范围变量
- knex.js - 选择带有连接的查询,其中响应字段包括表名?
- eclipse - 无法在 Eclipse 中将服务器添加到 Web 项目
- splinter - 如何在 Python 中通过 Splinter 访问 Selenium Webdriver
- reactjs - 如何使用带有 Typescript 的泛型将中继(graphql)连接映射到边缘节点
- html - 如果我必须连续对多个 div 使用 float left,有没有办法将它们与剩余空间居中?
- c++ - find() 没有返回可以使用的 int 值,并且在编译之前给出了错误
- sql - 多个组通过保持他们的订单
- constructor - Lua中这两段代码有什么区别