dennisameling / muuri-angular

Angular wrapper around the Muuri JavaScript library
MIT License
14 stars 5 forks source link

Feature Request: Events #4

Open wSedlacek opened 4 years ago

wSedlacek commented 4 years ago

Muuri features many events, it would be great if these could be bound to using Angular event building. https://github.com/haltu/muuri#grid-events

It may look something like this.

<div muuriGrid (synchronize)="updateCachedGrid($event)"></div>
dennisameling commented 4 years ago

@wSedlacek I just introduced an Events feature. It allows you to get the Grid object directly, so you can use it to subscribe to events etc.

Would this work for you, or do you prefer to have it like you mentioned?

<div muuriGrid (synchronize)="updateCachedGrid($event)"></div>
<div muuriGrid (add)="onAdd($event)"></div>
etc.

In the library's internals it would then look something like

export class MuuriGridDirective implements OnInit, OnDestroy {
    ...
    @Output() synchronize: EventEmitter<void> = new EventEmitter();
    @Output() layoutStart: EventEmitter<{items: Item[], isInstant: boolean}> = new EventEmitter();
    @Output() add: EventEmitter<{items: Item[]}> = new EventEmitter();
    etc.
    ...

    constructor(private elRef: ElementRef) {}

    ngOnInit(): void {
        this.init(this.elRef);
    }

    /**
     * Initialize the grid.
     */
    init(grid: ElementRef): void {
        this.gridObject = new Grid(grid.nativeElement, this.config);
        this.gridObject.on('synchronize', () => this.synchronize.emit());
        this.gridObject.on('layoutStart', (items, isInstant) => this.layoutStart.emit({items, isInstant}));
        this.gridObject.on('add', (items) => this.add.emit({items}));
    }
}

... which means that we have to keep track of all GridEvents, and when a new one is added in the main library, we'll need to add it as well. I'm happy to do that, but I just thought it'd be more efficient if the user can directly call grid.on(EVENT_NAME, () => ...) to leverage Muuri's GridEvents directly, which also gives them type hinting.

Please let me know which option you prefer 😊

wSedlacek commented 4 years ago

Being a wrapper for Muuri it would be best if abstracted to Angular conventions. I believe your approach here to be good however as you mentioned it does require some upkeep. I almost feel like some Proxy or Mixin type pattern could give us the same effect without the upkeep.

@angular/fire uses proxies to proxy all of it's firebase request to the firebase API simply take the promises and converting them to observables. In our case we would be converting each to an EventEmitter. We may also not need to use the @Output() if we add it to the @Directive() metadata.

In any case that solution would be much more complex so perhaps for that reason alone the upkeep makes more sense.