angular 5.0.0-beta+3
angular: ^5.0.0-beta+3 copied to clipboard
Fast and productive web framework
5.0.0-beta+2 #
New features #
-
Added support for named arguments in function calls in templates:
<span>Hello {{getName(includeExclamationPoint: true)}}</span>
NOTE: Because of the collision of syntax for both named arguments and
pipes, any pipes used as the value of a named argument need to be wrapped
in parentheses: func(namedArg: (pipeName | pipeVar:pipeVarValue)).
Bug fixes #
-
Changed the behavior of warnings around
@ViewChildren(...). It was more difficult than originally thought to warn on incorrect selector usage due to the semantics of components and dependency injection. In many cases false positives were flagged. Now, any unknown type is just ignored (it may still be invalid), and any invalid value throws a build error. For example:class A { // Might not be valid, but we no longer warn. @ViewChildren(SomeArbitraryType) List<SomeArbitraryType> someTypes; // We throw a build error. @ViewChildren(1234) List thisDoesNotWork; } -
Implicit static tear-offs and field invocations are now supported:
@Component( selector: 'example', template: ''' <!-- Invoking an implicit static field. --> <div>{{field()}}</div> <!-- Binding an implicit static tear-off. --> <div [invoke]="tearOff"></div> ''', ) class ExampleComponent { static String Function() field = () => 'Hello world'; static String tearOff() => 'Hello world'; }
5.0.0-beta+1 #
New features #
-
A warning is produced if the compiler removes any elements (such as
<script>) from your template. This may become an error in future versions of AngularDart. Closes #1280. -
A warning is produced if the selector provided to a query (such as
@ViewChildren(...)) is invalid and will not produce any elements at runtime. This may become an error in future versions of AngularDart. Closes #1220. -
It is now possible to annotate parts of a template with
@preserveWhitespaceinstead of opting into preserving whitespace for the entire template. Closes #1295:<div> <div class="whitespace-sensitive" @preserveWhitespace> Hello World! </div> </div> -
Added
package:angular/meta.dart, a series of utilities for additional static analysis checks and/or functions to retain semantics for migration purposes, starting withcastCallback1ForDirectiveandcastCallback2ForDirective. These methods are only intended to be used as stop-gaps for the lack of generic support in AngularDart directives and components. Closes #1489.
Bug fixes #
-
Fails the build immediately if an element in a component's
pipeslist is unresolved. -
Support inherited method tear-offs in event listeners. Previously, we only considered methods in the Component class itself. Closes #506.
-
Fixed a bug where
[attr.name.if]did not work on a static@HostBinding. Closes #1484.
Other improvements #
-
Fixed a bug where many queries (
@ViewChildren()and the like) generated additional runtime casts in production mode. Now in Dart2JS with--omit-implicit-checksthe casts are removed. -
Emits more optimized code when there are multiple data bindings in a row that are checked only once (such as
finalstrings). Previously we generated redundant code. -
Fixed an optimization issue when
@ViewChild()or@ContentChild()was used on a nested element (i.e. inside a<template>). The code that was produced accidentally created two queries instead of one. Closes #1455.
5.0.0-beta #
Welcome to the first release candidate of AngularDart v5.0.0, with full support
for Dart 2. Please note that an up-to-date copy of dev channel Dart SDK is
required (at least 2.0.0-dev.65 as of this writing) to use this version of
AngularDart. Additionally:
- Dartium is no longer supported. Instead, use the new DartDevCompiler
- Pub transformers are no longer used. Instead, use the new webdev CLI, or, for advanced users, the build_runner CLI.
More details of changes to Dart 2 for web users are available on our webiste.
We are no longer expecting further breaking changes as we get closer to a final release (which itself is pending a final release of the Dart 2 SDK). Please continue to report stability issues, bugs, or requests for small non-breaking enhancements.
Thanks, and enjoy AngularDart!
Dependency Injection #
Dependency injection was enhanced greatly for 5.0.0, primarily around using proper types (for Dart 2), and paths to enable much smaller code size (for everyone).
New features
-
Provider(andprovide) are soft deprecated, and in their place are four new classes with more precise type signatures. Additionally,Providernow supports an optional type argument<T>, making itProvider<T>.-
ValueProvider(Type, T)andValueProvider.forToken(OpaqueToken<T>, T)instead ofProvider(typeOrToken, useValue: ...). -
FactoryProvider(Type, T)andFactoryProvider.forToken(OpaqueToken<T>, T)instead ofProvider(typeOrToken, useFactory: ...). -
ClassProvider(Type, useClass: T)andClassProvider.forToken(OpaqueToken<T>, useClass: T)instead ofProvider(typeOrToken, useClass: ...)or an implicitType. -
ExistingProvider(Type, T)andExistingProvider.forToken(OpaqueToken<T>, T)instead ofProvider(typeOrToken, useExisting: ...).
-
-
OpaqueTokenis now much more useful. Previously, it could be used to define a custom, non-Typeto refer to something to be injected; commonly instead of types likeString. For example, you might use anOpaqueTokento refer to the a URL to download a file from:const downloadUrl = OpaqueToken('downloadUrl'); @Component( providers: [ Provider(downloadUrl, useValue: 'https://a-site.com/file.zip'), ], ) class Example { Example(@Inject(downloadUrl) String url) { // url == 'https://a-site.com/file.zip' } }First,
OpaqueTokenadds an optional type argument, makingOpaqueToken<T>. The type argument,T, should be used to refer to theTypeof the object this token should be bound to:const downloadUrl = OpaqueToken<String>('downloadUrl');Coupled with the new named
Providerclasses and their.forTokennamed constructor (see below), you now also have a way to specify the type of providers using type inference:@Component( providers: [ // This is now a Provider<String>. ValueProvider.forToken(downloadUrl, 'https://a-site.com/file.zip'), ], )Second,
MultiToken<T>has been added, and it extendsOpaqueToken<List<T>>. This is an idiomatic replacement for the now deprecatedmulti: trueargument to theProviderconstructor:const usPresidents = MultiToken<String>('usPresidents'); @Component( providers: [ ValueProvider.forToken(usPresidents, 'George'), ValueProvider.forToken(usPresidents, 'Abe'), ], ) class Example { Example(@Inject(usPresidents) List<String> names) { // names == ['George', 'Abe'] } }Third, we heard feedback that the
String-based name of tokens was insufficient for larger teams because the names could collide. Imagine 2 different tokens being registered with a name of'importantThing'! It is now possible (but optional) toextendeitherOpaqueTokenorMultiTokento create scoped custom token names:class DownloadUrl extends OpaqueToken<String> { const DownloadUrl(); } class UsPresidents extends MultiToken<String> { const UsPresidents(); } class Example { providers: const [ ValueProvider.forToken(DownloadUrl(), 'https://a-site.com/file.zip'), ValueProvider.forToken(UsPresidents(), 'George'), ValueProvider.forToken(UsPresidents(), 'Abe'), ], }Fourth, and finally, we'd like to repurpose
@Injectin the future, and let you write less to inject tokens. So,OpaqueTokenandMultiTokeninstances may now be used directly as annotations:class Example { Example(@DownloadUrl() String url, @UsPresidents() List<String> names) { // url == 'https://a-site.com/file.zip' // names == ['George', 'Abe'] } } -
InjectorFactory, a function type definition ofInjector Function([Injector parent]), was added and started to be used across the framework. It normally indicates the ability to create a newInjectorinstance with an optional parent. -
A new annotation,
@GenerateInjector, was added. It is now posibble to generate, at compile-time, a standaloneInjectorFactorymethod for providers, without explicitly wrapping in an@Component:// example.dart import 'example.template.dart' as ng; @GenerateInjector([ ClassProvider(HelloService), ]) final InjectorFactory rootInjector = ng.rootInjector$Injector; -
Modulehas been added as a new, more-typed way to encapsulate a collection ofProviderinstances. This is an optional feature to use instead of nestedconstlists to represent shared providers. For example:const httpModule = [ /* Other providers and/or modules. */ ]; const commonModule = [ httpModule, ClassProvider(AuthService, useClass: OAuthService), FactoryProvider.forToken(xsrfToken, useFactory: readXsrfToken), ];... you can represent this with the new typed
Modulesyntax:const httpModule = Module( /* ... Configuration ... */); const commonModule = Module( include: [httpModule], provide: [ ClassProvider(AuthService, useClass: OAuthService), FactoryProvider.forToken(xsrfToken, useFactory: readXsrfToken), ], );The advantages here are numerous:
-
Less ambiguity around ordering of providers. Engineers would tend to try and sort providers alphabetically, would of course, would lead to problems.
Modulespecifically outlines that order is significant, and thatincludeis processed beforeprovide. -
Modulerejects using aTypeimplicitly as aClassProvider. This removes additional ambiguity around supportingList<dynamic>, and while more verbose, should lead to more correct use. -
Moduletends to be more understandable by users of other dependency injection systems such as Guice or Dagger, and reads better than aconstList(which is a very Dart-only idiom).
NOTE: It is also possible to use
Modulein@GenerateInjector:@GenerateInjector.fromModules([ commonModule, ]) final InjectorFactory exampleFromModule = ng.exampleFromModule$Injector;NOTE: It is also possible to use
ModuleinReflectiveInjector:// Using ReflectiveInjector is strongly not recommended for new code // due to adverse effects on code-size and runtime performance. final injector = ReflectiveInjector.resolveAndCreate([ commonModule, ]); -
Breaking changes
-
OpaqueTokenno longer overridesoperator==orhashCode. In practice this should have no effect for most programs, but it does mean that effectively that onlyconstinstances ofOpaqueToken(orMultiToken) are valid. -
It is no longer valid to provide a token type of anything other than
Typeor anOpaqueToken(orMultiToken). In the past anything from aribtrary literals (such as a string -'iAmAToken') or a customconstinstance of a class were supported. -
For defining whether a component or directive should provide itself for injection,
Visibility.nonehas been renamedVisibility.localto make it more clear that it is accessable locally (withinprovidersfor example). -
Classes annotated with
@Componentor@Directiveare no longer treated like services annotated with@Injectable, and not accessible (by default) toReflectiveInjector.@Injectablecan always be added to these classes in order to return to the old behavior.
Bug fixes
-
Fixed a bug where calling
geton anInjectorinjected in the context of an@Componentor@Directive-annotated class and passing a second argument always returnednull(instead of that second argument) if the token was not found. -
Setting
@Component(visibility: Visibility.none) no longer applies toproviders, if any. Note thatVisibility.nonewas always renamedVisibility.localin breaking changes above. -
Fixed a bug where
Provider(SomeType)was not parsed correctly as an implicit use ofProvider(SomeType, useClass: SomeType). -
Fixed a bug where
<ReflectiveInjector>.get(X)would throw with a message of no provider found for X, even when the acutal cause was a missing downstream dependencyY. We now emit the correct message.
Other improvements
-
Some injection failures will display the chain of dependencies that were attempted before a token was not found (
'X -> Y -> Z') in development mode. We are working on making sure this better error message shows up always but it is likely to slip until after the v5 release. -
It is no longer a build warning to have an
@Injectable-annotated service with more than one constructor. This was originally meant to keep injection from being too ambiguous, but there are understood patterns now (first constructor), and there is no alternative present yet. We may re-add this as a warning if there ends up being a mechanism to pick a constructor in the future. -
It is no longer a build warning to have
@Injectable-annotated services with named constructor parameters. While they are still not supported for injected, they were always successfully ignored in the past, and showing a warning to the user on every build served no purpose. -
If a private class is annotated with
@Injectable()the compiler fails. In practice this caused a compilation error later in DDC/Dart2JS, but now the AngularDart compiler will not emit invalid code. -
Removed spurious/incorrect warnings about classes that are used as interfaces needing
@Injectable(or needing to be non-abstract), which are wrong and confusing. -
The compiler behind
initReflector()has changed implementations and now uses fully-scoped import statements instead of trying to figure out the original scope (including import prefixes) of your source code. This was not intended to be a breaking change.
Components and Templates #
New features
-
NgTemplateOutletaddedngTemplateOutletContextfor setting local variables in an embedded view. These variables are assignable to template input variables declared usinglet, which can be bound within the template. See theNgTemplateOutletdocumentation for examples. -
Added a lifecycle event
AfterChanges, which is similar toOnChanges, but with a much lower performance cost - it does not take any parameters and is suitable when you have multiple fields and you want to be notified when any of them change:class Comp implements AfterChanges { @Input() String field1; @Input() String field2; @override void ngAfterChanges() { print('Field1: $field1, Field2: $field2'); } } -
It is possible to directly request
ElementorHtmlElementtypes from content or view children instead ofElementRef(which is deprecated). For example:@Component( selector: 'uses-element', template: '<div #div>1</div>' ) class UsesElement { @ViewChild('div') // Could also be HtmlElement. Element div; } -
Additionally,
List<Element>andList<HtmlElement>for@ViewChildrenand@ContentChildrenno longer requireread: Element, and the type is correctly inferred the same as a single child is. -
Static properties and methods of a component may now be referenced without a receiver in the component's own template. For example:
Before:
ExampleComponentas receiver is necessary.@Component( selector: 'example', template: '<h1>{{ExampleComponent.title}}</h1>', ) class ExampleComponent { static String title; }After: No receiver is necessary.
@Component( selector: 'example', template: '<h1>{{title}}</h1>', ) class ExampleComponent { static String title; } -
@HostListener()can now automatically infer theconst ['$event']parameter when it is omitted but the bound method has a single argument:class Comp { @HostListener('click') void onClick(MouseEvent e) {} } -
Added
<ng-container>, an element for logical grouping that has no effect on layout. This enables use of the *-syntax for structural directives, without requiring the cost an HTML element.Before
<ul> <template ngFor let-user [ngForOf]="users"> <li *ngIf="user.visible">{{user.name}}</li> </template> </ul>After
<ul> <ng-container *ngFor="let user of users"> <li *ngIf="user.visible">{{user.name}}</li> </ng-container> </ul> -
In dev mode only, an attribute named
fromis now added to each<style>tag whose value identifies the source file URL and name of the component from which the styles originate. -
Support for the suffix
.iffor attribute bindings, both in a template and in a@HostBinding(). Accepts an expression of typebool, and adds an attribute iftrue, and removes it iffalseand closes https://github.com/dart-lang/angular/issues/1058:<!-- These are identical --> <button [attr.disabled]="isDisabled ? '' : null"></button> <button [attr.disabled.if]="isDisabled"></button> -
Add support for tear-offs in event handlers in the templates.
BEFORE:
<button (onClick)="clickHandler($event)">AFTER:
<button (onClick)="clickHandler">
Breaking changes
-
We now have a new, more stricter template parser, which strictly requires double quotes (
"...") versus single quotes, and in general enforces a stricter HTML-like syntax. It does produce better error messages than before. -
We removed support for
ngNonBindablein the new template syntax. -
The fields
inputs:,outputs:, andhost:have been removed from@Directive(...)and@Component(...). It is expected to use the member annotations (@Input(),@Output(),@HostBinding(),@HostListener()) instead. -
The default for
@Component(preserveWhitespace: ...)is nowtrue. Many improvements were put into the whitespace optimziation in order to make the results easier to understand and work around. -
<AsyncPipe>.transformno longer returns the (now removed)WrappedValuewhen a transformed result changes, and relies on regular change detection. -
Pipes no longer support private types in their
transformmethod signature. This method's type is now used to generate a type annotation in the generated code, which can't import private types from another library. -
Using
@deferredno longer supports the legacy bootstrap processes. You must userunApp(orrunAppAsync) to bootstrap the application without relying oninitReflector(). -
<ComponentRef>.componentTypealways throwsUnsupportedError, and will be removed in a later minor release. This removes our last invocation of.runtimeType, which has potentially severe code-size implications for some apps. -
QueryListfor@ViewChildrenand@ContentChildrenhas been removed, in favor of just a plainListthat is replaced with a new instance when the children change (instead of requiring a custom collection and listener):class Comp { @ViewChildren(ChildComponent) set viewChildren(List<ChildComponent> viewChildren) { // ... } // Can also be a simple field. @ContentChildren(ChildComponent) List<ChildComponent> contentChildren; } -
EventEmitterwas removed in favor usingStreamandStreamController. -
COMMON_DIRECTIVESwas renamedcommonDirectives. -
CORE_DIRECTIVESwas renamedcoreDirectives. -
COMMON_PIPESwas renamedcommonPipes. -
Private types can't be used in template collection literals bound to an input. This is a consequence of fixing a cast warning that is soon to be an error caused by the code generated for change detecting collection literals in templates. See https://github.com/dart-lang/angular/issues/844 for more information.
-
SafeInnerHtmlDirectiveis no longer injectable. -
The following types were never intended for external use and are no longer exported by
package:angular/security.dart:SafeHtmlImplSafeScriptImplSafeStyleImplSafeResourceUrlImplSafeUrlImplSafeValueImpl
To mark a value as safe, users should inject
DomSanitizationServiceand invoke the correspondingbypassSecurityTrust*()method, instead of constructing these types directly. -
ComponentResolverwas removed, andSlowComponentLoaderwas deprecated. -
Methods in lifecycle hooks have
voidreturn type. This is breaking change if the override doesn't specify return type and usesreturnwithout any value. To fix add avoidorFuture<void>return type to the override:class MyComp implements OnInit { @override void ngOnInit() { // ... } } -
Removed the rarely used
templateattribute syntax. Uses can be replaced with either the*micro-syntax, or a<template>element.Before
<div template="ngFor let item of items; trackBy: trackById; let i=index"> {{i}}: {{item}} </div>After
<!-- * micro-syntax --> <div *ngFor="let item of items; trackBy: trackById; let i=index"> {{i}}: {{item}} </div> <!-- <template> element --> <template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackById" let-i="index"> <div> {{i}}: {{item}} </div> </template> -
It is now a compile error to implement both the
DoCheckandOnChangeslifecycle interfaces.DoCheckwill never fill in values for theMapinOnChanges, so this compile-error helps avoid bugs and directs the user to useDoCheckandAfterChangesinstead. -
Using a suffix/unit for the
[attr.name.*]syntax other than the newly introduced[attr.name.if]is now a compile-error. These binding suffixes were silently ignored (users were likely confused with[style.name.px], which is supported).
Bug fixes
-
Fixed a bug where an
@deferredcomponents were still being linked to ininitReflector(). -
Fixed a bug where errors thrown in event listeners were sometimes uncaught by the framework and never forwarded to the
ExceptionHandler. -
Fixed a bug where
DatePipedidn't formatmillisecondsSinceEpochin the local time zone (consistent with how it formatsDateTime). -
Testability now includes
ComponentStateupdates. Due to prior use ofanimationFramecallback,NgTestBedwas not able to detect a stable state. -
String literals bound in templates now support Unicode escapes of the form
\u{?-??????}. This enables support for Unicode supplementary planes, which includes emojis! -
Inheriting from a class that defines a
@HostBinding()on a static member no longer causes the web compiler (Dartdevc or Dart2JS) to fail. We previously inherited these bindings and generated invalid Dart code. Given that static members are not inherited in the Dart language, it made sense to give a similar treatment to these annotations. Instance-level members are still inherited:class Base { @HostBinding('title') static const hostTitle = 'Hello'; @HostBinding('class') final hostClass = 'fancy'; } // Will have DOM of <fancy-button class="fancy"> but *not* title="Hello". @Component( selector: 'fancy-button', template: '...', ) class FancyButton extends Base {} -
Fixed a bug where a recursive type signature on a component or directive would cause a stack overflow. We don't support generic type arguments yet (the reified type is always
dynamic), but the compiler no longer crashes.
Other improvements
-
Types bound from generics are now properly resolved in a component when inheriting from a class with a generic type. For example, the following used to be untyped in the generated code:
class Container<T> { @Input() T value; } class StringContainerComponent implements Container<String> {} -
Both
ComponentFactoryandComponentRefnow have a generic type parameter<T>, which is properly reified whereTis the type of the component class. -
The
$implicit(iterable) value in*ngForis now properly typed whenever possible. It was previously always typed asdynamic, which caused dynamic lookups/calls at runtime, and hid compilation errors. -
The type of
<EmbeddedViewRef>.rootNodesand<ViewRefImpl>.rootNodeshas been tightened fromList<dynamic>toList<Node>(whereNodeis fromdart:html). -
A combination of compile errors and warnings are produced when it seem that
template,templateUrl,style, orstyleUrlsare either incorrect or missing when required. -
The compiler now reports an actionable error when an annotation is used on a private class member. We also report errors when various annotations are used improperly (but not in all cases yet).
-
The compiler optimizes
*ngIfusages where the content is pure HTML. -
The view compiler is able to tell when
exports: [ ... ]in an@Componentare static reads and are immutable (such asString). This allows us to optimize the generated code. -
Some changes to how template files import 'dart:core' to accommodate analyzer changes that make 'dynamic' a member of 'dart:core'. These should not have user-visible effects.
Application Bootstrap #
New features
-
The process for starting your AngularDart application changed significantly:
- For most applications, we now strongly recommend using the new
runAppfunction. Instead of starting your application by passing theTypeof an@Component-annotatedclass, you now pass aComponentFactory, the generated code for a component:
import 'package:angular/angular.dart'; import 'main.template.dart' as ng; void main() { runApp(ng.RootComponentNgFactory); } @Component( selector: 'root', template: 'Hello World', ) class RootComponent {}To provide top-level services, use the
createInjectorparameter, and pass a generatedInjectorFactoryfor a top-level annotated with@GenerateInjector:import 'package:angular/angular.dart'; import 'main.template.dart' as ng; void main() { runApp(ng.RootComponentNgFactory, createInjector: rootInjector); } class HelloService { void sayHello() => print('Hello!'); } @GenerateInjector([ ClassProvider(HelloService), ]) final InjectorFactory rootInjector = ng.rootInjector$Injector;A major difference between
runAppand previous bootstrapping code is the lack of theinitReflector()method or call, which is no longer needed. That means usingrunAppdisables the use ofSlowComponentLoaderandReflectiveInjector, two APIs that require this extra runtime metadata.To enable use of these classes for migration purposes, use
runAppLegacy:import 'package:angular/angular.dart'; // ignore: uri_has_not_been_generated import 'main.template.dart' as ng; void main() { runAppLegacy( RootComponent, createInjectorFromProviders: [ ClassProvider(HelloService), ], initReflector: ng.initReflector, ); }NOTE:
initReflectorandrunAppLegacydisables tree-shaking on any class annotated with@Componentor@Injectable. We strongly recommend migrating to therunApppattern. - For most applications, we now strongly recommend using the new
Breaking changes
-
The top-level function
bootstrapwas deleted. This function always threw a runtime exception since5.0.0-alpha+5, and was a relic of when a code transformer rewrote it automatically asbootstrapStatic. -
Dropped support for
@AngularEntrypointand rewriting entrypoints to automatically useinitReflector()andbootstrapStatic. This is no longer supported in the new build system. -
RenderComponentTypeis no longer part of the public API. -
<ApplicationRef>.componentFactories,.componentTypes,.zone, and.registerBootstrapListenerwere removed; these were used internally by the legacy router and not intended to be part of the public API. -
PLATFORM_INITIALIZERSwas removed. -
APP_INITIALIZERwas removed. A similar functionality can be accomplished using therunAppAsyncorrunAppLegacyAsyncfunctions with thebeforeComponentCreatedcallback. -
PlatformRefandPlatformRefImplwere removed.
Misc #
Breaking changes
-
<NgZone>.onStablehas been renamed toonTurnDone. -
<NgZone>.onUnstablehas been renamed toonTurnStart. -
The
contextparameter was removed from<TemplateRef>.createEmbeddedView. -
The following relatively unused fields and functions were removed:
APPLICATION_COMMON_PROVIDERSBROWSER_APP_COMMON_PROVIDERSBROWSER_APP_PROVIDERSPACKAGE_ROOT_URLErrorHandlingFnUrlResolverWrappedTimerWrappedValueZeroArgFunctionappIdRandomProviderFactorycoreBootstrapcoreLoadAndBootstrapcreateNgZonecreatePlatformdisposePlatformgetPlatform
-
Running within the
NgZonewill no longer cause addtional turns to occur within it's parent's zone.<NgZone>.run()will now run inside the parent zone'srun()function as opposed to the other way around. -
The compilation mode
--debug(sparingly used externally) is now no longer supported. Some flags and code paths in the compiler still check/support it but it will be removed entirely by the final release and should no longer be used. We will rely on assertion-based tree-shaking (fromDart2JS) going forward to emit debug-only conditional code.
Bug fixes
- We longer invoke
<ExceptionHandler>.callwith anullexception.
Other improvements
- Misspelled or otherwise erroneous annotations on classes now produce a more understandable error message, including the element that was annotated and the annotation that was not resolved.
4.0.0 #
We are now named package:angular instead of package:angular2. As such
you cannot pub upgrade from angular2 3.x -> angular2 4.x, and you need to
manually update your dependencies instead:
dependencies:
angular: ^4.0.0
AngularDart will start tracking the upcoming Dart 2.0 alpha SDK, and as such,
4.0.0 will be the last stable release that fully supports Dart 1.24.0. We may
release small patches if needed, but otherwise the plan is to release 4.0.0 and
then immediately start working on 5.0.0-alpha, which uses the new Dart SDK.
Breaking changes #
-
@Pipe-annotated classes are no longer considered@Injectable, in that they aren't usable within aReflectiveInjector. You can get this behavior back by adding the@Injectable()annotation to the@Pipe-annotated class. Similar changes are in progress for@Componentand@Directive. -
PLATFORM_{PIPES|DIRECTIVES|PROVIDERS}, which was only supported in an older version of the compiler, was removed. All of these must be manually included in lists in an@Directiveor@Componentannotation. -
Removed
formDirectivesfromCOMMON_DIRECTIVESlist; replaceCOMMON_DIRECTIVESwith[CORE_DIRECTIVES, formDirectives]for components that use forms directives. -
Forms API has been moved to a new package,
angular_forms, which is going to be versioned and maintained alongside the core framework. This should allow better segmentation of code and easier contributions. -
The router package is now being published separate as
package:angular_router(not throughpackage:angular/router.dart). In the near future it will be updated to a more Dart idiomatic "2.0" router, but for now it is an exact replica of the previous router. -
Removed
@{Component|Directive}#queries. This is replable using the same member-level annotation (i.e.@{Content|View}Child{ren}). -
DynamicComponentLoaderwas renamedSlowComponentLoaderto encourage users to preferComponentLoader. Additionally, argumentsprojectableNodes:andonDestroy:callbacks were removed - they were mostly unused, and confusing since they were undocumented. -
Removed
angular/platform/browser_static.dart; replace imports withangular/angular.dart. -
Removed
angular/platform/common_dom.dart; replace imports withangular/angular.dart. -
Removed
angular/testing.dart; Useangular_testpackage instead. -
Removed
angular/platform/testing.dart. -
Removed
platform/testing/browser_static.dart. -
Removed
MockNgZone. -
Removed
ViewEncapsulation.native, which is no longer supported. -
Renamed
FORM_DIRECTIVEStoformDirectives. -
Removed
angular/common.dart; replace imports withangular/angular.dart. -
Removed
angular/compiler.dart; compiler should only be invoked via the transformers or viapkg:builddirectly usingangular/source_gen.dart. -
Deprecated
@View()annotation was completely removed. -
Deprecated second parameter to
ExceptionHandlerwas completely removed. -
Removed the runtime (
dart:mirrors-based) interpreter. It is now required to always use the AngularDart transformer to pre-compile the code, even during development time in Dartium.package:angular2/reflection.dartwas also removed. -
The
bootstrapfunction now always throws a runtime exception, and both it andbootstrapStaticare accessible viaangular.dartinstead ofplatform/browser.dartandplatform/browser_static.dart#357. -
Returning
falsefrom an event handler will no longer cancel the event. See #387 for details. -
Removed
QueryandViewQuery. Please useContentChild/ContentChildrenandViewChild/ViewChildrenin their place instead. -
Removed the
use_analyzerflag for the transformer. This is alwaystrue. #404. -
Removed all other unused or unsupported flags from the transformer. There is now a single
CompilerFlagsclass that is universally supported for all build systems. -
Removed a number of classes that were never intended to be public.
-
Removed the second parameter to
ExceptionHandler, which was a no-op anyway. -
Removed
outputsfield fromDirective. Outputs now must be declared using inlineOutputannotations.
New features #
-
Added support for functional directives: lightweight, stateless directives that apply a one-time transformation.
-
One is defined by annotating a public, top-level function with
@Directive(). -
The function parameters specify its dependencies, similar to the constructor of a regular directive.
-
Only the
selectorandprovidersparameters of the@Directive()annotation are permitted, because the other parameters are stateful. -
The function return type must be
void.
-
@Directive(selector: '[autoId]')
void autoIdDirective(Element element, IdGenerator generator) {
element.id = generator.next();
}
- Added
visibilityproperty toDirective. Directives and components that don't need to be injected can setvisibility: Visibility.nonein their annotation. This prevents the compiler from generating code necessary to support injection, making the directive or component non-injectable and reducing the size of your application.
// This component can't be injected by other directives or components.
@Component(selector: 'my-component', visibility: Visibility.none)
class MyComponent { ... }
- Added
ComponentLoader, a high-level imperative API for creating components at runtime. It uses internal code-paths that already existed, and is much more future proof.ComponentLoaderis usable within a@Directive(), an@Component(), and injectable services.
// An `ExampleComponent`s generated code, including a `ComponentFactory`.
import 'example.template.dart' as ng;
class AdBannerComponent implements AfterViewInit {
final ComponentLoader _loader;
AdBannerComponent(this._loader);
@override
ngAfterViewInit() {
final component = _loader.loadDetached(ng.ExampleComponentNgFactory);
// Do something with this reference.
}
}
-
You can now directly inject
dart:html'sElementorHtmlElementinstead ofElementRef, which is "soft deprecated" (will be deprecated and removed in a future release). -
findContainerhas now been exposed from NgForm allowing easier creation of custom form implementations. -
setUpControlhas been exposed from the forms API to allow forms to setup their controls easier. -
Inheritance for both component and directive metadata is now complete! Any field or method-level annotations (
@Input,@Output,@ViewChild|Children,@ContentChild|Children) are now inherited through super types (extends,implements,with) #231:
class BaseComponent {
@Input()
String name;
}
// Also has an input called "name" now!
@Component(selector: 'comp')
class ConcreteComponent extends BaseComponent {}
- Inputs that are of type
boolnow receive a default value oftrueinstead of a value ofnullor an empty string. This allows a much more HTML-friendly syntax for your components:
<!-- All of these set a value of disabled=true -->
<fancy-button disabled></fancy-button>
<fancy-button [disabled]></fancy-button>
<fancy-button [disabled]="true"></fancy-button>
<!-- Value of disabled=false -->
<fancy-button [disabled]="false"></fancy-button>
@Component()
class FancyButton {
@Input()
bool disabled = false;
}
- Added
exports: [ ... ]to@Component, which allows the limited use of top-level fields and static methods/fields in a template without making an alias getter in your class. Implements #374.
import 'dart:math' show max;
@Component(
selector: 'comp',
exports: const [
max,
],
// Should write '20'
template: '{{max(20, 10)}}',
)
class Comp {}
-
Limitations:
- Only top-level fields that are
const(notfinal) can be exported.
- Only top-level fields that are
-
Added
@deferredas the first "compile-time" directive (it has no specific runtime code nor is it listed in adirectives: [ ... ]list. Implements #406.
import 'package:angular2/angular2.dart';
import 'expensive_comp.dart' show ExpensiveComp;
@Component(
selector: 'my-comp',
directives: const [ExpensiveComp],
template: r'''
<expensive-comp @deferred></expensive-comp>
''',
)
class MyComp {}
-
Added preliminary support for component inheritance. Components now inherit inputs, outputs, host bindings, host listeners, queries, and view queries from all supertypes.
-
We use a new open sourcing tool called "CopyBara" that greatly simplifies both releasing and taking open source contributions. We are able to release to github more often, and accept PRs much more easily. You can view our bleeding
github-syncbranch for what has yet to be merged intomaster. -
We no longer emit
ng_*.jsonfiles as part of the compile process #276. -
Attribute selectors (
<ng-content select="custom-action[group='1']">) is now supported #237. -
Lifecycle interfaces no longer need to be "re-implemented" on classes in order for the compiler to pick them up - we now respect the dependency chain #19.
-
Provider(useValue: ...)now accepts "complex const data structures", with the caveat that your data structure must not be invoking a private constructor #10.
Deprecations #
- Support for shadow piercing combinators
/deep/and>>>to prevent style encapsulation is now deprecated./deep/is already deprecated and will be removed in Chrome 60. Its alias>>>is limited to the static profile of selectors, meaning it's not supported in style sheets. Continued use of these combinators puts Angular at risk of incompatibility with common CSS tooling.::ng-deepis a drop-in replacement, intended to provide the same functionality as/deep/and>>>, without the need to use deprecated or unsupported CSS syntax #454.
Bug fixes #
-
Compiler now warns when annotations are added to private classes or functions.
-
Compiler now warns when injecting into a field that is non-existent.
-
Fixed a long-standing bug on
ngSwitchbehavior in Dartium. -
Fixed a bug in
@deferredwhen nested views has DI bindings. Fixes #578. -
The transformer now fails if any unsupported arguments are passed in.
-
Fixed a bug where
@deferreddid not work nested inside of<template>:
<template [ngIf]="someCondition">
<expensive-comp @deferred></expensive-comp>
</template>
-
ngFormnow allowsonSubmitto be called with anullvalue. -
Using
inputs|outputsin the@Componentannotation to rename an existing@Input()or@Output()now logs and fails the build during compilation. -
Symbol collisions with
dart:htmlno longer cause a runtime exception, all framework use ofdart:htmlis now scoped behind a prefixed import. -
Properly annotate methods in generated
.template.dartcode with@override. -
Updated the documentation for
OnInitandOnDestroyto mention more specifics about the contract and document "crash detection" cases where they may be called more than once. -
*ngIfnow properly checks that inputs do not change during change detection #453. -
Properly typed
TrackByFnas anintnot anum#431. -
Import aliases are supported by the compiler #245.
Performance #
-
Various small reductions to the size of generated code and the runtime.
-
Directives now generate their own change detector class (behind the scenes) instead of the code being re-created into every component that uses a directive.
-
Remove redundant calls to
dbg(...)in dev-mode. This reduces the amount of work done and speeds up developer runtimes, such as those using the DartDevCompiler (DDC). -
Some change detection code that was duplicated across all generated templates were moved internally to a new
AppView#detectHostChangesmethod. -
Introduced a new
AppViewDatastructure in the generated code that decreases code size ~2% or more in some applications due to better code re-use and emit in dart2js. -
We no longer change detect literals and simple
finalproperty reads. -
Some of the enums used to manage change detection state have been simplified to
intin order to reduce the cost in the generated code.
3.1.0 #
New features #
-
Exposed
TouchFunctionandChangeFunctiontypedefs to make the transition to strong-mode easier for teams relying on these function definitions. We might remove them in a future release when they are no longer needed. -
Added a flag to use an experimental new compiler that uses the Dart analyzer to gather metadata information. This flag will be turned on by default in
4.0:
transformers:
angular2/transform/codegen:
use_analyzer: true
WARNING: Using use_analyzer: true requires discontinuing use of the
platform_* options, and fails-fast if both flags are used. See
https://goo.gl/68VhMa for details.
WARNING: Using use_analyser: true doesn't yet work with most third-party
packages due to a bug.
Deprecations #
- Using
dart:mirrors(i.e. running AngularDart without code generation) is now formally deprecated. In4.0+code generation will be the only way to run an AngularDart application, even in development mode. Please ensure you are using our transformer: https://goo.gl/rRHqO7.
Bug fixes #
-
CSS errors are now just warnings, and can be ignored. This is due to using a CSS parser for encapsulation - and the AngularDart transformer aggressively runs on all CSS files in a given package. We hope to make this smoother in a future release.
-
Do not generate
throwOnChangeschecks outside of dev-mode.
Performance #
- Bypasses the deprecated event plugin system for all native DOM events.
- At runtime
interpolateis now represented by multiple functions (faster). KeyValueDiffer(NgClass,NgStyle) optimized for initial add/removals.- No longer generates event handler registrations for directive outputs.
3.0.0 #
New features #
composeValidatorsandcomposeAsyncValidatorsnow part of the public API.angular2/testing.dartincludes a test-onlyisDebugModefunction.- (Forms)
AbstractControl.markAsDirtynow emits a status change event.
Breaking changes #
-
Requires at least Dart SDK
1.23.0. -
Injecting
nullis no longer supported. -
Remove unused
usePropertyargument in DIProviderapi. -
ReflectionCapabilities.isReflectionEnabledrenamed toreflectionEnabled. -
Malformed CSS warnings are errors now.
-
Removed forms async validators. Alternative:
control.valueChange((value) { rpc.validate(change).then((errors) { if (errors != null) control.setErrors(errors); }); }); -
Removed
TitleService. To update the title, usedart:html:document.title = 'My title'; -
DynamicComponentLoadernow has a simplified API:loadAsRoot,loadAsRootIntoNodereplaced by a singleloadmethod that always creates the component root node instead of hoisting into an existing node. -
Removed
viewBindingsfromComponent. This has been interchangeable withviewProvidersfor a while now.BEFORE:
dart @Component(viewBindings: const [])AFTER:
dart @Component(viewProviders: const []) -
Removed
EventManagerfrom the public API. Code generation is now closer todocument.addEventListenerand having this interception layer would not allow further optimizations. -
Removed
IterableDifferFactoryandKeyValueDifferFactoryfrom the public API. We have planned compiler optimizations that will no longer allow overriding our diffing implementations. Looking into alternatives before a final3.0.0release that are lower cost. -
ASYNC_VALIDATORScan no longer return aStreaminstance, onlyFuture. -
The experimental
NgTestBedwas removed. Usepackage:angular_testnow. -
By default, the
ExceptionHandleris aBrowserExceptionHandler, which prints exceptions to the console. If you don't want this behavior (i.e. releasing to production), make sure to override it. -
ElementRef.nativeElementis nowfinal(no setter). -
DOM adapter is now completely removed from the API and generated code
-
A
nameparameter is now required for all@Pipe(...)definitions:BEFORE:
dart @Pipe(name: 'uppercase')AFTER:
dart @Pipe('uppercase') -
DomEventsPluginnow requires a strongly typed interface todart:html. -
Nullis no longer propagated as an initial change value. Code should be updated to either deliver a different initial value or components with an@Input()should have an appropriate default value.BEFORE
<my-component [value]="null"></my-component> ... String _value; set value(String value) { _value = value ?? 'Default name'; }AFTER
String _value = 'Default name'; set value(String value) { _value = value; } -
Removed the
isFirstChange()method ofSimpleChange. Instead, check whetherpreviousValueisnull. -
Removed
NgPlural, deprecated as of 2.1.0. -
Removed
ObservableListDiffFactory, deprecated as of 2.1.0. -
Event handlers are bound at initialization time. Therefore, the following will no longer work, because
clickHandlerisnullduring initialization.@Component( selector: 'my-component', template: '<div (click)="clickHandler($event)"></div>') class MyComponent { Function clickHandler; } -
Removed
Component.moduleId, which was unused.
Deprecations #
@Viewwill be removed in4.0, only use@Componentinstead.EventEmitteris now@Deprecated: UseStreamandStreamController.ngSwitchCasereplacesngSwitchWhen(soft deprecation).XHRis deprecated, along with the runtime/reflective compiler.IterableDiffersandKeyValueDiffersare deprecated. The cost of looking up to see if a custom differ is available is too high for almost no use. Before they're removed, we'll have other customization options.
Bug fixes #
- Updated various documentation to make cleaner and use Dart, not TS, samples.
- Perf: Added performance improvements around generated code and type inference.
- Fix: Key-value differ now detects removals when first key moves.
- Fix:
<ng-content select="...">does not emit incorrect code (regression). - Perf: Optimized how reflective providers are resolved on application startup.
ngSwitchWhennow properly compares identity in Dartium.Component/Directive#selectoris now a@requiredproperty.- Angular warns in the console if using Dartium without checked mode.
- Various performance improvements for both code size and runtime.
- Various Dart idiomatic/style guide updates to the codebase.
ngIfnow throws again if the bound value changes during change detection.- Fixed a bug where the router didn't work on a root path in IE11.
- Fixed generated code that caused a strong-mode warning on
AppView<...>. - Fixed a bug where DDC didn't work properly with "pure"
Pipes. - Some simple types are now propagated to the generated
.template.dartfile. - When setting up a new
NgControl,valueAccessorno longer can throw an NPE - Re-enabled
strong-modeanalysis within the project, and fixed some errors.
Refactoring #
- We now use the formal
<T>generic type syntax for methods, not/*<T>*/. - Removed
NgZoneImpl, all the code exists inNgZonenow. - We now generate specific code for view and content children (faster).
- Projectable nodes now use the visitor pattern in
AppView. - In generated
.template.dartchange detected primitives are typed. - Moved
renderTypeas a static class member in generated code.
2.2.0 #
API changes #
- Breaking changes
- Using
@ViewQuery|Children|Content|in a constructor is no longer valid. This caused significant extra code to need to be generated for a case that is relatively rare. Code can safely be moved into a setter in most cases.
- Using
BEFORE ```dart class MyComponent { QueryList
MyComponent(@ContentChildren(ChildComponent) this._childComponents); } ```
AFTER ```dart class MyComponent { QueryList
@ContentChildren(ChildComponent) set childComponents(QueryList
Bug fixes #
- Importing
angular2/reflection.dartnow works properly.
2.1.1 #
API changes #
- Introduced
angular2/reflection.dartas canonical way to opt-in to mirrors. In 2.2.0 it will be considered deprecated to enable runtime reflection by any other means.
2.1.0 #
API changes #
- Breaking changes
NgControlStatusno longer included inCOMMON_DIRECTIVESand inFORM_DIRECTIVES. Needs to be manually included in your bootstrap or migrated off of
- Deprecations
- Using
@Queryin a component constructor; move to field-level Renderer: Usedart:htmldirectlyNgControlStatus: A form control should set class they are interested inNgPlural: Was never formally supported in Angular Dart. Recommend usingpackage:intlwith getters on your@Componentpointing to anIntl.messagecall until we have formal template support (planned)ObservableListDiff: Not properly implemented, will re-introduce later
- Using
- Removed support for
InjectorModule- was never formally supported
Bug fixes and other changes #
- Documentation fixes and cleanups across the codebase
- Code size and runtime performance improvements across the codebase
- More reduction of STRONG_MODE exceptions in the compiler
- Removed
InjectorModulecode (from TS-transpiler era) - Fixed a bug with
ExceptionHandlernot being called during change detection - Fixed a bug where controls were not marked dirty when an error was set
2.0.0 Release #
API changes #
- Implemented NgTestBed to improve test infrastructure goo.gl/NAXXlN.
- Removed Metadata classes used for angular annotations.
- Added ComponentState to provide push change detection with better ergonomics and code generation.
- ViewContainerRef.createEmbeddedView index parameter removed instead introduced insertEmbeddedView.
- Added support for minimal code generation when user explicitly marks component with preserveWhitespace:false.
Bug fixes and other changes #
- Improved ngFor performance.
- Improved shared style host performance.
- Improved @ViewChild/@ViewChildren performance.
- Code and documentation cleanups.
- Strong mode fixes.
2.0.0-beta.22 #
API changes #
- POTENTIALLY BREAKING Observable features new use the new
observablepackage, instead ofobserve. - Removed
Renderer.createViewRoot.
Bug fixes and other changes #
- Improved compiler errors.
- Fixes to reduce code size.
- Support the latest
pkg/build. - Now require Dart SDK 1.19 at a minimum.
- Added
.analysis_optionsto enforce a number of style rules.
2.0.0-beta.21 #
Our push towards better performance has started showing results in this release. This update provides 5-10% speedup in components. >20% reduction in Dart code size emitted from compiler.
API changes #
- Added support for '??' operator in template compiler.
- Removed unused animation directives to create more Darty/compile time version.
- Removed unused i18n pipes to prepare for dart:intl based solution.
- Language facades removed (isPresent, isBlank, getMapKey, normalizeBool, DateWrapper, RegExpWrapper, StringWrapper, NumberWrapper, Math facades, SetWrapper, ListWrapper, MapWrapper, StringMapWrapper, ObservableWrapper, TimerWrapper).
- Deprecated unused ROUTER_LINK_DSL_TRANSFORM.
- Refactor(element.dart) is now app_element.dart.
- AppView moved to app_view. DebugAppView moved to debug/debug_app_view.dart.
- The deprecated injection Binding and bind have been removed.
- Remove global events and disposables (instead of :window type targets, use dart APIs).
Bug fixes and other changes #
- Improved change detection performance.
- Improved error messages reported by template compiler.
- Optimized [class.x]="y" type bindings.
- Switched to js_util for browser_adapter to make angular CSP compliant.
- Started strongly typing element members in compiled template code.
- Cheatsheet and code docs updated.
- Router fixes
2.0.0-beta.20 #
API changes #
- Added ngBeforeSubmit event to ngForm API to allow better validation.
- Global events removed from event binding syntax (dart:html APIs provide better alternative).
Bug fixes and other changes #
- Reduced template code size.
- Cleanup of facades.
- Class Documentation updates.
- ngForm submit changed to sync.
- Removed disposables in generated template code.
2.0.0-beta.19 #
API changes #
- Remove existing implementation of web workers, to be replaced in the future with Dart import override for dart:html.
Bug fixes and other changes #
- Remove throwOnChanges parameter from all change detection calls in generated template.dart.
- Unused and empty assertArrayOfStrings API removed.
- Update BrowserDomAdapter from dart:js to package:js.
- Reset change detection to guard against template exception.
- Delete unused files.
- Clean up the NgIf directive and remove facades.
- Enabled Travis-CI.
- Update tests that should only run in the browser.
- Add angular transformer which deletes any pre-existing generated files from Bazel.
- Add DI library entrypoint to support VM tests.
- Fix the Math facade (improper annotation): @Deprecated(description).
- Clean up animation classes.
- Remove library name declarations.
- Run dart formatter on all code.
- Remove unused testing/lang_utils.dart.
2.0.0-beta.18 #
This is the first release of Angular 2 for Dart that is written directly in Dart, instead of generated from TypeScript.
API changes #
The Provider constructor and provide() function are now more intuitive when
they have a single argument.
Before, const Provider(Foo) or provide(Foo) would provide a null object.
To provide a Foo object, you had to use const Provider(Foo, useClass:Foo) or
provide(Foo, useClass:Foo). Now you can omit the useClass:Foo. Either of the
following provides a Foo instance:
const Provider(Foo)
// or
provide(Foo)
If you want the old behavior, change your code to specify useValue:
const Provider(Foo, useValue: null)
// or
provide(Foo, useValue: null)
Known issues #
- Some types of dependency injection don't work. (https://github.com/dart-lang/angular2/issues/10)
Bug fixes and other changes #
- Fix lower bound of pkg/build dependency.
- Fixes for dependency upper bounds: build and protobuf.
- Bumping min version of pkg/intl and pkg version.
- Remove redundant declaration of
el. - Security Update. Secure Contextual Escaping Implementation.
- Fix Intl number formatting.
- Enforce strong mode for angular2.dart.
- Updating README and CONTRIBUTING.md for first release.
- Enforce dartfmt for dart/angular2.
- Add //dart/angular2/build_defs with default resolved_identifiers.
- Import cleanup.
- Annotate browser-only tests.
- Include .gitignore in files sent to GitHub.
- Fix a strong mode error in angular2 (strong mode type inference miss).
- Add compiler tests.
- Delete unused libraries in lib/src.
- Updated pubspec: authors, description, homepage.
- Angular strong mode fixes for DDC support.
- Add _LoggerConsole implementation of Console for the TemplateCompiler.
- Mark Binding and bind() as deprecated. Replaced by Provider and provide().