Our pure JavaScript Scheduler component


Post by rrajewski »

Currently I am using the Columns.Renderer and "paint" event for to use angular components for the Resources and Events on the grid. Is there a better/recommended approach for this? If not, is there a way to get a reference to the dom element for the Event without listening for the Event paint? The Columns.Renderer passes in the cellElement, which makes the process easier. There does not seem to be the equivalent for the EventRenderer

Column.Renderer https://www.bryntum.com/docs/scheduler/ ... g-renderer
EventRenderer https://www.bryntum.com/docs/scheduler/ ... ntRenderer

example code:
 if (event.type === 'eventpaint' || event.type === 'eventrepaint') {
      // event paint must be before final rendering of event, settimeout so that it runs after
      setTimeout(() => {
        if (event.element) {
          const container = document.createElement('app-event');

          const factory = this.cfr.resolveComponentFactory(EventComponent);
          // use viewcontainerRef so that components are destroyed when this component is destroyed
          const componentRef = this.viewContainerRef.createComponent(factory);

          (<EventComponent>componentRef.instance).event = event.eventRecord;
          componentRef.changeDetectorRef.detectChanges();

          event.element.innerHTML = '';
          event.element.appendChild(container);
          this.renderer.appendChild(container, componentRef.location.nativeElement);

          const destroyObserver = new MutationObserver(function(e) {
            if (e[0].removedNodes) {
              console.log('removed', e, e[0].removedNodes);
              componentRef.destroy();
              pull(this.observers, (event.element as any)._destroyObserver);
              destroyObserver.disconnect();
            }
          });

          this.observers.push(destroyObserver);
          destroyObserver.observe(event.element, {
            childList: true
          });
        }
      });

Post by johan.isaksson »

Hi,

Unfortunately the eventRenderer is called earlier in the process than the columns renderer, and no element is available yet. I have created a ticket on refactoring this https://app.assembla.com/spaces/bryntum/tickets/7352-have-element-available-when-eventrenderer-is-called/details, but it is a pretty big change and not likely to happen soon.

For react we are planning to support JSX in renderers, such as this:
{
  field : 'x',
  text : 'x',
  renderer: ({record}) => <MyComponent text={record.text} />
}
Might be we can offer something similar for Angular. Have created a ticket on investigating that: https://app.assembla.com/spaces/bryntum/tickets/7353-renderers-should-be-able-to-return-angular-components/details.

If you have thoughts on how you would want it to work, please share and we will see what we can do
Best regards,
Johan Isaksson

Post by rrajewski »

Thanks for the update! It would be awesome if we could use use the angular component directly in the renderer.

In the meantime, would it be possible to add an 'afterRender' event or equivalent for the Resources and Events that we could listen for, in order to attach the angular component? Then we could be sure the scheduler is finished updating the dom before we add the component. A 'destroyed' event would also be nice so that we could clean it up when the grid is scrolled.

Post by johan.isaksson »

There is a private event triggered after rendering an event, or actually two: `eventPaint` and `eventRepaint`. Repaint is used when an element is reused, so you would need to listen to both. Parameters are { scheduler, eventRecord, resourceRecord, element }.

I will raise a discussion internally on making these or some new event public, and also discuss adding a `eventDestroyed` event. Ticket created here: https://app.assembla.com/spaces/bryntum ... ic/details
Best regards,
Johan Isaksson

Post Reply