OLD | NEW |
(Empty) | |
| 1 /** |
| 2 * Bootstrapping for Angular applications via [app:factory](#angular-app-factory
) for development, |
| 3 * or [app:factory:static](#angular-app-factory-static) for production. |
| 4 * |
| 5 * In your `main()` function, you bootstrap Angular by explicitly defining and a
dding a module for |
| 6 * your application: |
| 7 * |
| 8 * import 'package:angular/angular.dart'; |
| 9 * import 'package:angular/application_factory.dart'; |
| 10 * |
| 11 * class MyModule extends Module { |
| 12 * MyModule() { |
| 13 * type(HelloWorldController); |
| 14 * } |
| 15 * } |
| 16 * |
| 17 * main() { |
| 18 * applicationFactory() |
| 19 * .addModule(new MyModule()) |
| 20 * .run(); |
| 21 * } |
| 22 * |
| 23 * In the code above, we use [applicationFactory](#angular-app-factory) to |
| 24 * take advantage of [dart:mirrors] |
| 25 * (https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart-mirrors
) during |
| 26 * development. When you run the app in Dartium the [app:factory](#angular-app-f
actory) |
| 27 * implementation allows for quick edit-test development cycle. |
| 28 * |
| 29 * Note that you must explicitly import both `angular.dart` and `application_fac
tory.dart` at |
| 30 * the start of your file. |
| 31 * |
| 32 * For production, transformers defined in your `pubspec.yaml` file convert the
code to |
| 33 * use the [app:factory:static](#angular-app-factory-static) when you run `pub b
uild`. Instead of |
| 34 * relying on mirrors (which disable tree-shaking and thus generate large JS siz
e), the transformers |
| 35 * generate getters, setters, annotations, and factories needed by Angular. The
result is that |
| 36 * `dart2js` can than enable tree-shaking and produce smaller output. |
| 37 * |
| 38 * To enable the transformers add this rule as shown below to your `pubspec.yaml
`: |
| 39 * |
| 40 * name: angular_dart_example |
| 41 * version: 0.0.1 |
| 42 * dependencies: |
| 43 * angular: '>= 0.9.11' |
| 44 * browser: any |
| 45 * unittest: any |
| 46 * |
| 47 * transformers: |
| 48 * - angular |
| 49 * |
| 50 * If your app structure makes use of directories for storing your templates, |
| 51 * you must also specify rules for `html_files` to ensure that the transformers
pick up those |
| 52 * files. You only need to specify the HTML files; the parser will infer the cor
rect `.dart` and |
| 53 * CSS files to include. |
| 54 * |
| 55 * For example: |
| 56 * |
| 57 * transformers: |
| 58 * - angular: |
| 59 * html_files: |
| 60 * - lib/_some_library_/_some_component_.html |
| 61 * |
| 62 * If you need a way to build your app without transformers, you can use |
| 63 * [staticApplicationFactory](#angular-app-factory-static@id_staticApplicationFa
ctory) directly, |
| 64 * instead of [applicationFactory](#angular-app-factory@id_dynamicApplication).
See the |
| 65 * documentation for the [app:factory:static](#angular-app-factory-static) libra
ry definition for |
| 66 * more on this use case. |
| 67 */ |
| 68 library angular.app; |
| 69 |
| 70 import 'dart:html' as dom; |
| 71 |
| 72 import 'package:intl/date_symbol_data_local.dart'; |
| 73 import 'package:di/di.dart'; |
| 74 import 'package:angular/angular.dart'; |
| 75 import 'package:angular/perf/module.dart'; |
| 76 import 'package:angular/core/module_internal.dart'; |
| 77 import 'package:angular/core/registry.dart'; |
| 78 import 'package:angular/core_dom/module_internal.dart'; |
| 79 import 'package:angular/directive/module.dart'; |
| 80 import 'package:angular/formatter/module_internal.dart'; |
| 81 import 'package:angular/routing/module.dart'; |
| 82 import 'package:angular/introspection_js.dart'; |
| 83 |
| 84 /** |
| 85 * This is the top level module which describes all Angular components, |
| 86 * including services, formatters and directives. When instantiating an Angular
application |
| 87 * through [applicationFactory](#angular-app-factory), AngularModule is automati
cally included. |
| 88 * |
| 89 * You can use AngularModule explicitly when creating a custom Injector that nee
ds to know |
| 90 * about Angular services, formatters, and directives. When writing tests, this
is typically done for |
| 91 * you by the [SetUpInjector](#angular-mock@id_setUpInjector) method. |
| 92 * |
| 93 |
| 94 */ |
| 95 class AngularModule extends Module { |
| 96 AngularModule() { |
| 97 install(new CoreModule()); |
| 98 install(new CoreDomModule()); |
| 99 install(new DecoratorFormatter()); |
| 100 install(new FormatterModule()); |
| 101 install(new PerfModule()); |
| 102 install(new RoutingModule()); |
| 103 |
| 104 type(MetadataExtractor); |
| 105 value(Expando, elementExpando); |
| 106 } |
| 107 } |
| 108 |
| 109 /** |
| 110 * The Application class provides the mechanism by which Angular creates, config
ures, |
| 111 * and runs an application. There are two implementations for this abstract clas
s: |
| 112 * |
| 113 * - [app:factory](#angular-app-factory), which is intended for development. In
this |
| 114 * mode Angular uses |
| 115 * [dart:mirrors](https://api.dartlang.org/apidocs/channels/stable/dartdoc-vie
wer/dart-mirrors) |
| 116 * to dynamically generate getters, setters, annotations, and factories at run
time. |
| 117 * - [app:factory:static](#angular-app-factory-static) is used as part of `pub |
| 118 * build` by transformers that generate the getters, setters, annotations, |
| 119 * and factories needed by Angular. |
| 120 * Because the code is statically generated, `dart2js` can then use full tree-
shaking for |
| 121 * minimal output size. |
| 122 * |
| 123 * Refer to the documentation for [angular.app](#angular-app) for details of how
to use |
| 124 * applicationFactory to bootstrap your Angular application. |
| 125 * |
| 126 */ |
| 127 abstract class Application { |
| 128 static _find(String selector, [dom.Element defaultElement]) { |
| 129 var element = dom.window.document.querySelector(selector); |
| 130 if (element == null) element = defaultElement; |
| 131 if (element == null) { |
| 132 throw "Could not find application element '$selector'."; |
| 133 } |
| 134 return element; |
| 135 } |
| 136 |
| 137 final VmTurnZone zone = new VmTurnZone(); |
| 138 final AngularModule ngModule = new AngularModule(); |
| 139 final List<Module> modules = <Module>[]; |
| 140 dom.Element element; |
| 141 |
| 142 /** |
| 143 * Creates a selector for a DOM element. |
| 144 */ |
| 145 dom.Element selector(String selector) => element = _find(selector); |
| 146 |
| 147 Application(): element = _find('[ng-app]', dom.window.document.documentElement
) { |
| 148 modules.add(ngModule); |
| 149 ngModule..value(VmTurnZone, zone) |
| 150 ..value(Application, this) |
| 151 ..factory(dom.Node, (i) => i.get(Application).element); |
| 152 } |
| 153 |
| 154 /** |
| 155 * Returns the injector for this module. |
| 156 */ |
| 157 Injector injector; |
| 158 |
| 159 Application addModule(Module module) { |
| 160 modules.add(module); |
| 161 return this; |
| 162 } |
| 163 |
| 164 Injector run() { |
| 165 publishToJavaScript(); |
| 166 return zone.run(() { |
| 167 var rootElements = [element]; |
| 168 Injector injector = createInjector(); |
| 169 ExceptionHandler exceptionHandler = injector.get(ExceptionHandler); |
| 170 initializeDateFormatting(null, null).then((_) { |
| 171 try { |
| 172 var compiler = injector.get(Compiler); |
| 173 var viewFactory = compiler(rootElements, injector.get(DirectiveMap)); |
| 174 viewFactory(injector, rootElements); |
| 175 } catch (e, s) { |
| 176 exceptionHandler(e, s); |
| 177 } |
| 178 }); |
| 179 return injector; |
| 180 }); |
| 181 } |
| 182 |
| 183 /** |
| 184 * Creates an injector function that can be used for retrieving services as well
as for |
| 185 * dependency injection. |
| 186 */ |
| 187 Injector createInjector(); |
| 188 } |
OLD | NEW |