Skip to content

Instantly share code, notes, and snippets.

@gund
Last active July 28, 2017 12:14
Show Gist options
  • Save gund/7e278e17a843a8de5c7c818997df0510 to your computer and use it in GitHub Desktop.
Save gund/7e278e17a843a8de5c7c818997df0510 to your computer and use it in GitHub Desktop.
Run angular application in custom zone

This shows how you can customize zone behavior in which Angular App will run.

Can be useful for example if you want to intercept all events that angular dispatches to your handlers.

First, create a custom-zone.ts file:

import 'zone.js';

interface TaskInfo {
  delegate: ZoneDelegate;
  current: Zone;
  target: Zone;
  task: Task;
  applyThis: any;
  applyArgs: any;
}

let customZone: Zone;

export function getCustomZone() {
  return customZone || (customZone = createCustomZone());
}

function createCustomZone() {
  return Zone.current.fork({
    name: 'CustomZone',
    onInvokeTask: (delegate: ZoneDelegate, current: Zone, target: Zone, task: Task, applyThis: any,
      applyArgs: any): any => {
      const taskInfo = handleTask({ delegate, current, target, task, applyThis, applyArgs });
      return delegate.invokeTask(taskInfo.target, taskInfo.task, taskInfo.applyThis, taskInfo.applyArgs);
    }
  });
}

function handleTask(taskInfo: TaskInfo): TaskInfo {
  if (taskInfo.task.type === 'eventTask') {
    taskInfo = handleEvent(taskInfo, taskInfo.task['eventName']);
  }
  return taskInfo;
}

function handleEvent(taskInfo: TaskInfo, type: string): TaskInfo {
  const { applyArgs } = taskInfo;

  makeEvtNonCancellable(applyArgs[0]);

  return taskInfo;
}

function makeEvtNonCancellable(e: Event) {
  e.preventDefault = () => void 0;

  delete e.returnValue;

  Object.defineProperty(e, 'returnValue', {
    enumerable: true,
    configurable: false,
    get: () => true,
    set: () => void 0,
  });
}

And then just wrap angular bootstrapping inside this zone:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { getCustomZone } from './custom-zone';
import { AppModule } from './app/app.module';

getCustomZone().run(() =>
  platformBrowserDynamic().bootstrapModule(AppModule)
);

This will intercept all events and make them non cancellable (not very useful but you can customize to run ot any particular element etc).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment