From c8947d77bf2125b44f8501788318e7eeb1043de7 Mon Sep 17 00:00:00 2001 From: Jeremy Elbourn Date: Fri, 29 May 2015 16:27:54 -0700 Subject: [PATCH] chore(material): move dialog to TypeScript. --- .../dialog/{dialog.js => dialog.ts} | 163 +++++++++--------- .../material/dialog/{index.js => index.ts} | 45 +++-- 2 files changed, 102 insertions(+), 106 deletions(-) rename modules/angular2_material/src/components/dialog/{dialog.js => dialog.ts} (62%) rename modules/examples/src/material/dialog/{index.js => index.ts} (63%) diff --git a/modules/angular2_material/src/components/dialog/dialog.js b/modules/angular2_material/src/components/dialog/dialog.ts similarity index 62% rename from modules/angular2_material/src/components/dialog/dialog.js rename to modules/angular2_material/src/components/dialog/dialog.ts index 6e510da1ce..d56b88c918 100644 --- a/modules/angular2_material/src/components/dialog/dialog.js +++ b/modules/angular2_material/src/components/dialog/dialog.ts @@ -1,17 +1,21 @@ -import {DynamicComponentLoader, ElementRef, ComponentRef, onDestroy, DomRenderer} from 'angular2/angular2'; -import {bind, Injector} from 'angular2/di'; +import { + Component, + Directive, + View, + Parent, + ElementRef, + DynamicComponentLoader, + ComponentRef, + DomRenderer +} from 'angular2/angular2'; +import {bind, Injector, Injectable, FORWARD_REF} from 'angular2/di'; + import {ObservableWrapper, Promise, PromiseWrapper} from 'angular2/src/facade/async'; import {isPresent, Type} from 'angular2/src/facade/lang'; import {DOM} from 'angular2/src/dom/dom_adapter'; import {MouseEvent, KeyboardEvent} from 'angular2/src/facade/browser'; import {KEY_ESC} from 'angular2_material/src/core/constants'; -// TODO(radokirov): Once the application is transpiled by TS instead of Traceur, -// add those imports back into 'angular2/angular2'; -import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations'; -import {Parent} from 'angular2/src/core/annotations_impl/visibility'; -import {View} from 'angular2/src/core/annotations_impl/view'; - // TODO(jelbourn): Opener of dialog can control where it is rendered. // TODO(jelbourn): body scrolling is disabled while dialog is open. // TODO(jelbourn): Don't manually construct and configure a DOM element. See #1402 @@ -21,11 +25,10 @@ import {View} from 'angular2/src/core/annotations_impl/view'; // TODO(jelbourn): Pre-built `alert` and `confirm` dialogs. // TODO(jelbourn): Animate dialog out of / into opening element. -var _nextDialogId = 0; - /** * Service for opening modal dialogs. */ +@Injectable() export class MdDialog { componentLoader: DynamicComponentLoader; domRenderer: DomRenderer; @@ -39,13 +42,12 @@ export class MdDialog { * Opens a modal dialog. * @param type The component to open. * @param elementRef The logical location into which the component will be opened. + * @param parentInjector + * @param options * @returns Promise for a reference to the dialog. */ - open( - type: Type, - elementRef: ElementRef, - parentInjector: Injector, - options: MdDialogConfig = null): Promise { + open(type: Type, elementRef: ElementRef, parentInjector: Injector, + options: MdDialogConfig = null): Promise { var config = isPresent(options) ? options : new MdDialogConfig(); // Create the dialogRef here so that it can be injected into the content component. @@ -57,61 +59,63 @@ export class MdDialog { var backdropRefPromise = this._openBackdrop(elementRef, contentInjector); // First, load the MdDialogContainer, into which the given component will be loaded. - return this.componentLoader.loadIntoNewLocation( - MdDialogContainer, elementRef).then(containerRef => { - // TODO(tbosch): clean this up when we have custom renderers (https://github.com/angular/angular/issues/1807) - // TODO(jelbourn): Don't use direct DOM access. Need abstraction to create an element - // directly on the document body (also needed for web workers stuff). - // Create a DOM node to serve as a physical host element for the dialog. - var dialogElement = this.domRenderer.getHostElement(containerRef.hostView.render); - DOM.appendChild(DOM.query('body'), dialogElement); + return this.componentLoader.loadIntoNewLocation(MdDialogContainer, elementRef) + .then(containerRef => { + // TODO(tbosch): clean this up when we have custom renderers + // (https://github.com/angular/angular/issues/1807) + // TODO(jelbourn): Don't use direct DOM access. Need abstraction to create an element + // directly on the document body (also needed for web workers stuff). + // Create a DOM node to serve as a physical host element for the dialog. + var dialogElement = this.domRenderer.getHostElement(containerRef.hostView.render); + DOM.appendChild(DOM.query('body'), dialogElement); - // TODO(jelbourn): Use hostProperties binding to set these once #1539 is fixed. - // Configure properties on the host element. - DOM.addClass(dialogElement, 'md-dialog'); - DOM.setAttribute(dialogElement, 'tabindex', '0'); + // TODO(jelbourn): Use hostProperties binding to set these once #1539 is fixed. + // Configure properties on the host element. + DOM.addClass(dialogElement, 'md-dialog'); + DOM.setAttribute(dialogElement, 'tabindex', '0'); - // TODO(jelbourn): Do this with hostProperties (or another rendering abstraction) once ready. - if (isPresent(config.width)) { - DOM.setStyle(dialogElement, 'width', config.width); - } - if (isPresent(config.height)) { - DOM.setStyle(dialogElement, 'height', config.height); - } + // TODO(jelbourn): Do this with hostProperties (or another rendering abstraction) once + // ready. + if (isPresent(config.width)) { + DOM.setStyle(dialogElement, 'width', config.width); + } + if (isPresent(config.height)) { + DOM.setStyle(dialogElement, 'height', config.height); + } - dialogRef.containerRef = containerRef; + dialogRef.containerRef = containerRef; - // Now load the given component into the MdDialogContainer. - return this.componentLoader.loadNextToExistingLocation( - type, containerRef.instance.contentRef, contentInjector).then(contentRef => { + // Now load the given component into the MdDialogContainer. + return this.componentLoader.loadNextToExistingLocation( + type, containerRef.instance.contentRef, contentInjector) + .then(contentRef => { - // Wrap both component refs for the container and the content so that we can return - // the `instance` of the content but the dispose method of the container back to the - // opener. - dialogRef.contentRef = contentRef; - containerRef.instance.dialogRef = dialogRef; + // Wrap both component refs for the container and the content so that we can return + // the `instance` of the content but the dispose method of the container back to the + // opener. + dialogRef.contentRef = contentRef; + containerRef.instance.dialogRef = dialogRef; - backdropRefPromise.then(backdropRef => { - dialogRef.whenClosed.then((_) => { - backdropRef.dispose(); - }); + backdropRefPromise.then(backdropRef => { + dialogRef.whenClosed.then((_) => { backdropRef.dispose(); }); + }); + + return dialogRef; + }); }); - - return dialogRef; - }); - }); } /** Loads the dialog backdrop (transparent overlay over the rest of the page). */ - _openBackdrop(elementRef:ElementRef, injector: Injector): Promise { - return this.componentLoader.loadIntoNewLocation( - MdBackdrop, elementRef, injector).then( (componentRef) => { - // TODO(tbosch): clean this up when we have custom renderers (https://github.com/angular/angular/issues/1807) - var backdropElement = this.domRenderer.getHostElement(componentRef.hostView.render); - DOM.addClass(backdropElement, 'md-backdrop'); - DOM.appendChild(DOM.query('body'), backdropElement); - return componentRef; - }); + _openBackdrop(elementRef: ElementRef, injector: Injector): Promise { + return this.componentLoader.loadIntoNewLocation(MdBackdrop, elementRef, injector) + .then((componentRef) => { + // TODO(tbosch): clean this up when we have custom renderers + // (https://github.com/angular/angular/issues/1807) + var backdropElement = this.domRenderer.getHostElement(componentRef.hostView.render); + DOM.addClass(backdropElement, 'md-backdrop'); + DOM.appendChild(DOM.query('body'), backdropElement); + return componentRef; + }); } alert(message: string, okMessage: string): Promise { @@ -163,8 +167,10 @@ export class MdDialogRef { return this._contentRef.instance; } - // The only time one could attempt to access this property before the value is set is if an access occurs during - // the constructor of the very instance they are trying to get (which is much more easily accessed as `this`). + // The only time one could attempt to access this property before the value is set is if an + // access occurs during + // the constructor of the very instance they are trying to get (which is much more easily + // accessed as `this`). throw "Cannot access dialog component instance *from* that component's constructor."; } @@ -203,13 +209,11 @@ export class MdDialogConfig { */ @Component({ selector: 'md-dialog-container', - hostListeners: { - 'body:^keydown': 'documentKeypress($event)' - } + hostListeners: {'body:^keydown': 'documentKeypress($event)'}, }) @View({ templateUrl: 'angular2_material/src/components/dialog/dialog.html', - directives: [MdDialogContent] + directives: [FORWARD_REF(() => MdDialogContent)] }) class MdDialogContainer { // Ref to the dialog content. Used by the DynamicComponentLoader to load the dialog content. @@ -234,13 +238,22 @@ class MdDialogContainer { } } +/** + * Simple decorator used only to communicate an ElementRef to the parent MdDialogContainer as the + * location + * for where the dialog content will be loaded. + */ +@Directive({selector: 'md-dialog-content'}) +class MdDialogContent { + constructor(@Parent() dialogContainer: MdDialogContainer, elementRef: ElementRef) { + dialogContainer.contentRef = elementRef; + } +} /** Component for the dialog "backdrop", a transparent overlay over the rest of the page. */ @Component({ selector: 'md-backdrop', - hostListeners: { - 'click': 'onClick()' - } + hostListeners: {'click': 'onClick()'}, }) @View({template: ''}) class MdBackdrop { @@ -256,15 +269,3 @@ class MdBackdrop { this.dialogRef.close(); } } - - -/** - * Simple decorator used only to communicate an ElementRef to the parent MdDialogContainer as the location - * for where the dialog content will be loaded. - */ -@Directive({selector: 'md-dialog-content'}) -class MdDialogContent { - constructor(@Parent() dialogContainer: MdDialogContainer, elementRef: ElementRef) { - dialogContainer.contentRef = elementRef; - } -} diff --git a/modules/examples/src/material/dialog/index.js b/modules/examples/src/material/dialog/index.ts similarity index 63% rename from modules/examples/src/material/dialog/index.js rename to modules/examples/src/material/dialog/index.ts index f33e9db36b..945851fcd1 100644 --- a/modules/examples/src/material/dialog/index.js +++ b/modules/examples/src/material/dialog/index.ts @@ -1,23 +1,22 @@ -import {bootstrap, ElementRef, ComponentRef} from 'angular2/angular2'; -import {MdDialog, MdDialogRef, MdDialogConfig} from 'angular2_material/src/components/dialog/dialog' +import {bootstrap, ElementRef, ComponentRef, Component, View} from 'angular2/angular2'; +import { + MdDialog, + MdDialogRef, + MdDialogConfig +} from 'angular2_material/src/components/dialog/dialog'; import {UrlResolver} from 'angular2/src/services/url_resolver'; import {commonDemoSetup, DemoUrlResolver} from '../demo_common'; import {bind, Injector} from 'angular2/di'; import {isPresent} from 'angular2/src/facade/lang'; -// TODO(radokirov): Once the application is transpiled by TS instead of Traceur, -// add those imports back into 'angular2/angular2'; -import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations'; -import {View} from 'angular2/src/core/annotations_impl/view'; - @Component({ selector: 'demo-app', - appInjector: [MdDialog] + appInjector: [MdDialog], }) @View({ templateUrl: './demo_app.html', - directives: [] + directives: [], }) class DemoApp { dialog: MdDialog; @@ -43,16 +42,16 @@ class DemoApp { return; } - this.dialog.open(SimpleDialogComponent, - this.elementRef, this.injector, this.dialogConfig).then(ref => { - this.dialogRef = ref; - ref.instance.numCoconuts = 777; + this.dialog.open(SimpleDialogComponent, this.elementRef, this.injector, this.dialogConfig) + .then(ref => { + this.dialogRef = ref; + ref.instance.numCoconuts = 777; - ref.whenClosed.then(result => { - this.dialogRef = null; - this.lastResult = result; - }); - }); + ref.whenClosed.then(result => { + this.dialogRef = null; + this.lastResult = result; + }); + }); } close() { @@ -62,7 +61,7 @@ class DemoApp { @Component({ selector: 'simple-dialog', - properties: ['numCoconuts'] + properties: ['numCoconuts'], }) @View({ template: ` @@ -70,7 +69,7 @@ class DemoApp {

There are {{numCoconuts}} coconuts.

Return:

- ` + `, }) class SimpleDialogComponent { numCoconuts: number; @@ -95,9 +94,5 @@ class SimpleDialogComponent { export function main() { commonDemoSetup(); - bootstrap(DemoApp, [ - bind(UrlResolver).toValue(new DemoUrlResolver()) - ]); + bootstrap(DemoApp, [bind(UrlResolver).toValue(new DemoUrlResolver())]); } - -