5.0.0
angular
5.0.0
Welcome to AngularDart v5.0.0, with full support for Dart 2. Please note that
this release is not compatible with older versions of Dart 1.XX. 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.
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,Provider
now 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)
and
ClassProvider.forToken(OpaqueToken<T>, useClass: T)
instead of
Provider(typeOrToken, useClass: ...)
or an implicitType
. -
ExistingProvider(Type, T)
and
ExistingProvider.forToken(OpaqueToken<T>, T)
instead of
Provider(typeOrToken, useExisting: ...)
.
-
-
OpaqueToken
is now much more useful. Previously, it could be used to
define a custom, non-Type
to refer to something to be injected; commonly
instead of types likeString
. For example, you might use anOpaqueToken
to 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,
OpaqueToken
adds an optional type argument, making
OpaqueToken<T>
. The type argument,T
, should be used to refer to the
Type
of the object this token should be bound to:const downloadUrl = OpaqueToken<String>('downloadUrl');
Coupled with the new named
Provider
classes and their.forToken
named
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 extends
OpaqueToken<List<T>>
. This is an idiomatic replacement for the now
deprecatedmulti: true
argument to theProvider
constructor: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) toextend
eitherOpaqueToken
orMultiToken
to 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
@Inject
in the future, and let
you write less to inject tokens. So,OpaqueToken
andMultiToken
instances 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 newInjector
instance with an optional parent. -
A new annotation,
@GenerateInjector
, was added. It is now posibble to
generate, at compile-time, a standaloneInjectorFactory
method 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;
-
Module
has been added as a new, more-typed way to encapsulate a collection
ofProvider
instances. This is an optional feature to use instead of
nestedconst
lists 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
Module
syntax: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.Module
specifically outlines that order is significant,
and thatinclude
is processed beforeprovide
. -
Module
rejects using aType
implicitly as aClassProvider
. This
removes additional ambiguity around supportingList<dynamic>
, and
while more verbose, should lead to more correct use. -
Module
tends to be more understandable by users of other dependency
injection systems such as Guice or Dagger, and reads better than a
const
List
(which is a very Dart-only idiom).
NOTE: It is also possible to use
Module
in@GenerateInjector
:@GenerateInjector.fromModules([ commonModule, ]) final InjectorFactory exampleFromModule = ng.exampleFromModule$Injector;
NOTE: It is also possible to use
Module
inReflectiveInjector
:// 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
-
OpaqueToken
no longer overridesoperator==
orhashCode
. In practice
this should have no effect for most programs, but it does mean that
effectively that onlyconst
instances ofOpaqueToken
(orMultiToken
)
are valid. -
It is no longer valid to provide a token type of anything other than
Type
or anOpaqueToken
(orMultiToken
). In the past anything from aribtrary
literals (such as a string -'iAmAToken'
) or a customconst
instance of
a class were supported. -
For defining whether a component or directive should provide itself for
injection,Visibility.none
has been renamedVisibility.local
to make it
more clear that it is accessable locally (withinproviders
for example). -
Classes annotated with
@Component
or@Directive
are no longer treated
like services annotated with@Injectable
, and not accessible (by default)
toReflectiveInjector
.@Injectable
can always be added to these classes
in order to return to the old behavior.
Bug fixes
-
Fixed a bug where calling
get
on anInjector
injected in the context of
an@Component
or@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 to
providers
, if any. Note thatVisibility.none
was always renamed
Visibility.local
in 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
-
NgTemplateOutlet
addedngTemplateOutletContext
for 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 theNgTemplateOutlet
documentation 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
Element
orHtmlElement
types 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@ViewChildren
and@ContentChildren
no 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:
ExampleComponent
as 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
from
is 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
.if
for attribute bindings, both in a template and
in a@HostBinding()
. Accepts an expression of typebool
, and adds an
attribute iftrue
, and removes it iffalse
and closes
#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">
-
It is now possible to annotate parts of a template with
@preserveWhitespace
instead of opting into preserving whitespace for the
entire template. [Closes #1295][#1295]:<div> <div class="whitespace-sensitive" @preserveWhitespace> Hello World! </div> </div>
-
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. -
A warning is produced if the selector provided to a query (such as
@ViewChildren(...)
) is invalid and will not produce any elements at
runtime. NOTE: 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 no warning. @ViewChildren(SomeArbitraryType) List<SomeArbitraryType> someTypes; // We throw a build error. @ViewChildren(1234) List thisDoesNotWork; }
-
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))
.
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
ngNonBindable
in 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>.transform
no longer returns the (now removed)WrappedValue
when a transformed result changes, and relies on regular change detection. -
Pipes no longer support private types in their
transform
method 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
@deferred
no longer supports the legacy bootstrap processes. You
must userunApp
(orrunAppAsync
) to bootstrap the application without
relying oninitReflector()
. -
<ComponentRef>.componentType
always 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. -
QueryList
for@ViewChildren
and@ContentChildren
has been removed, in
favor of just a plainList
that 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; }
-
EventEmitter
was removed in favor usingStream
andStreamController
. -
COMMON_DIRECTIVES
was renamedcommonDirectives
. -
CORE_DIRECTIVES
was renamedcoreDirectives
. -
COMMON_PIPES
was 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 #844 for more
information. -
SafeInnerHtmlDirective
is no longer injectable. -
The following types were never intended for external use and are no longer
exported bypackage:angular/security.dart
:SafeHtmlImpl
SafeScriptImpl
SafeStyleImpl
SafeResourceUrlImpl
SafeUrlImpl
SafeValueImpl
To mark a value as safe, users should inject
DomSanitizationService
and
invoke the correspondingbypassSecurityTrust*()
method, instead of
constructing these types directly. -
ComponentResolver
was removed, andSlowComponentLoader
was deprecated. -
Methods in lifecycle hooks have
void
return type. This is breaking change
if the override doesn't specify return type and usesreturn
without any
value. To fix add avoid
orFuture<void>
return type to the override:class MyComp implements OnInit { @override void ngOnInit() { // ... } }
-
Removed the rarely used
template
attribute 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
DoCheck
andOnChanges
lifecycle interfaces.DoCheck
will never fill in values for theMap
in
OnChanges
, so this compile-error helps avoid bugs and directs the user to
useDoCheck
andAfterChanges
instead. -
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
@deferred
components were still being linked to in
initReflector()
. -
Fixed a bug where errors thrown in event listeners were sometimes uncaught
by the framework and never forwarded to theExceptionHandler
. -
Fixed a bug where
DatePipe
didn't formatmillisecondsSinceEpoch
in the
local time zone (consistent with how it formatsDateTime
). -
Testability now includes
ComponentState
updates. Due to prior use of
animationFrame
callback,NgTestBed
was 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 alwaysdynamic
), but the compiler no longer crashes. -
Fails the build immediately if an element in a component's
pipes
list is
unresolved. -
Fixed a bug where
[attr.name.if]
did not work on a static@HostBinding
. -
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'; }
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
ComponentFactory
andComponentRef
now have a generic type parameter
<T>
, which is properly reified whereT
is the type of the component
class. -
The
$implicit
(iterable) value in*ngFor
is 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>.rootNodes
and<ViewRefImpl>.rootNodes
has
been tightened fromList<dynamic>
toList<Node>
(whereNode
is from
dart:html
). -
A combination of compile errors and warnings are produced when it seem that
template
,templateUrl
,style
, orstyleUrls
are 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
*ngIf
usages where the content is pure HTML. -
The view compiler is able to tell when
exports: [ ... ]
in an@Component
are 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. -
Fixed a bug where many queries (
@ViewChildren()
and the like) generated
additional runtime casts in production mode. Now in Dart2JS with
--omit-implicit-checks
the casts are removed. -
Emits more optimized code when there are multiple data bindings in a row
that are checked only once (such asfinal
strings). 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. -
Improved error message for binding incorrectly typed event handlers. This
moves the check from event dispatch time, to event subscription time,
meaning it may be a breaking change if you had an incorrectly typed event
handler bound to a output that never fired.
Application Bootstrap
New features
-
The process for starting your AngularDart application changed significantly:
- For most applications, we now strongly recommend using the new
runApp
function. Instead of starting your application by passing theType
of
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
createInjector
parameter, and pass
a generatedInjectorFactory
for 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
runApp
and previous bootstrapping code is the
lack of theinitReflector()
method or call, which is no longer needed.
That means usingrunApp
disables the use ofSlowComponentLoader
and
ReflectiveInjector
, 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:
initReflector
andrunAppLegacy
disables tree-shaking on any
class annotated with@Component
or@Injectable
. We strongly recommend
migrating to therunApp
pattern. - For most applications, we now strongly recommend using the new
Breaking changes
-
The top-level function
bootstrap
was 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
@AngularEntrypoint
and rewriting entrypoints to
automatically useinitReflector()
andbootstrapStatic
. This is no longer
supported in the new build system. -
RenderComponentType
is no longer part of the public API. -
<ApplicationRef>
.componentFactories
,.componentTypes
,.zone
, and
.registerBootstrapListener
were removed; these were used internally by the
legacy router and not intended to be part of the public API. -
PLATFORM_INITIALIZERS
was removed. -
APP_INITIALIZER
was removed. A similar functionality can be accomplished
using therunAppAsync
orrunAppLegacyAsync
functions with the
beforeComponentCreated
callback. -
PlatformRef
andPlatformRefImpl
were removed.
Misc
New features
- Added
package:angular/meta.dart
, a series of utilities for additional
static analysis checks and/or functions to retain semantics for migration
purposes, starting withcastCallback1ForDirective
and
castCallback2ForDirective
. These methods are only intended to be used as
stop-gaps for the lack of generic support in AngularDart directives and
components.
Breaking changes
-
<NgZone>.onStable
has been renamed toonTurnDone
. -
<NgZone>.onUnstable
has been renamed toonTurnStart
. -
The
context
parameter was removed from<TemplateRef>.createEmbeddedView
. -
The following relatively unused fields and functions were removed:
APPLICATION_COMMON_PROVIDERS
BROWSER_APP_COMMON_PROVIDERS
BROWSER_APP_PROVIDERS
PACKAGE_ROOT_URL
ErrorHandlingFn
UrlResolver
WrappedTimer
WrappedValue
ZeroArgFunction
appIdRandomProviderFactory
coreBootstrap
coreLoadAndBootstrap
createNgZone
createPlatform
disposePlatform
getPlatform
-
Running within the
NgZone
will 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>.call
with anull
exception.
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.
angular_forms
2.0.0
New Features
-
Add AbstractControlGroup and AbstractNgForm to allow infrastructure to
create their own form systems that can be backed by types such as a proto,
or have different control group logic. Allow NgFormModel and NgControlGroup
to work with abstract group. -
reset
method added toAbstractControl
andAbstractControlDirective
. -
RequiredValidator
now has arequired
input. This allows therequired
property to be toggled at runtime. Previously, this could only be set
statically at compile time. -
Control.invalid
getter added. -
Control.markAsPristine
added. This will clear thedirty
property. -
Add
ngDisabled
input to all Control directives. -
Add
MemorizedForm
directive. This is a form that will not remove controls
if the control is taken out of the view, for example with a [NgIf]. -
Add
disabled
state toAbstractControl
models. Note: This is not yet
supported in the template-driven directives. -
Add
markAsUntouched
method toAbstractControl
. -
Add a type annotation,
T
, toAbstractControl
, which is tied to the type
ofvalue
. -
ControlGroup
nowextends AbstractControl<Map<String, dynamic>>
. -
ControlArray
nowextends AbstractControl<List>
.
Breaking Changes
-
Use value from AbstractControl for valueChanges event instead of internal
variable. Allows code to more easily subclass AbstractControl. -
Remove deprecated
NG_VALUE_ACCESSOR
token. UsengValueAccessor
instead. -
Abstract
updateValue
method added toAbstractControl
. All subclasses of
AbstractControl
will need to implement this method. -
NgControlName
will no longer initialize withnull
if a value is
specified by 'ngModel'. -
The
touched
property ofControl
s is now propagated to parents /
children. -
NgControlGroup
can no longer be injected directly. It can still be
injected as aControlContainer
. -
NgControlName
andNgFormControl
can no longer be injected directly. They
can still be injected as aNgControl
. -
The following directives are no longer injectable:
CheckboxControlValueAccessor
DefaultValueAccnessor
MaxLengthValidator
MinLengthValidator
NgControlStatus
NgSelectOption
NumberValueAccessor
PatternValidator
RadioControlValueAccessor
RequiredValidator
-
Add
ControlValueAccessor.onDisabledChanged()
method. All implementations
ofControlValueAccessor
need to add this method. -
Remove
include
andexclude
methods fromControlGroup
. These can be
replaced with calls tomarkAsEnabled
andmarkAsDisabled
instead.Before:
controlGroup.include('foo');
After:
controlGroup.controls['foo'].markAsEnabled();
-
CheckboxControlValueAccessor
now implementsControlValueAccessor<bool>
andRadioControlValueAccessor
now implements
ControlValueAccessor<RadioButtonState>
. Previously, they were both
ControlValueAccessor<dynamic>
. -
Remove
optionals
param fromControlGroup
constructor. This has been
replaced bydisabled
state for allControls
. See
#1037 for more details. -
AbstractControl.find
now only accepts a String. To supply a list, use
AbstractControl.findPath
instead. Also, forfind
orfindPath
,
ControlArray
index is now callingint.parse
instead of expecting a raw
number. -
Properly typed the generic parameter on subclasses of
AbstractControlDirective
. Now,NgControl.control
will return a
Control
, andControlContainer.control
will return aControlGroup
.
There may be some unnecessary casts that can now be cleaned up. -
FormBuilder
instance methodsgroup
,control
, andarray
have been
removed. ForFormBuilder.control
, just callnew Control(value, validator)
directly. ForFormBuilder.group
andFormBuilder.array
, use
the static methodsFormBuilder.controlGroup
and
FormBuilder.controlArray
, respectively.FormBuilder
is no longer
Injectable
. -
Changed type of
AbstractControl.statusChanges
fromStream<dynamic>
to
Stream<String>
. This now matches the type forAbstractControl.status
,
which as always been aString
. -
Allow expressions for maxlength/minlength validators. Breaking change does
not support string values for maxlength/minlength anymore.minlength="12"
now should be written[minlength]="12"
Bug fixes
-
Add a not selector to ngForm for memorizedForm since memorized_form is now
in angular_forms. This fixes the DIRECTIVE_EXPORTED_BY_AMBIGIOUS error when
using: <form #form="ngForm" memorizedForm> -
Don't throw a null pointer exception in NgFormModel if a directives asks for
a Control value before the form is initialized.
angular_test
2.0.0
New Features
-
Supported
FutureOr<void>
forbeforeChangeDetection
. -
NgZoneStabilizer
waits for the longest pending timer duringupdate()
. -
Added
isStable
API toNgTestStabilizer
. -
Made
NgTestStabilizerFactory
public.
Breaking Changes
-
Removed
throwsInAngular
. UsethrowsA
. -
Removed
NgTestFixture#query/queryAll
, as debug-mode is being turned down. -
Run
DelegatingNgTestStabilizer
stabilizers one by one instead of run all
at once.update()
for each stabilizers will be run at least once. After
that, it will only be run if the current stabilizer is not stable. -
pub run angular_test
was entirely removed. Similar functionality is
supported out of the box bybuild_runner
:
$ pub run build_runner test
-
Removed built-in support for
package:pageloader
. The current version of
pageloader
relies ondart:mirrors
, which is being removed from the web
compilers (dart2js, dartdevc). There is a new version ofpageloader
in
development that uses code generation. We'll consider re-adding support once
available or through another package (i.e.angular_pageloader
or similar). -
Adding stabilizers to
NgTestBed
now takes a factory function of type
NgTestStabilizer Function(Injector)
, which is aliased as
NgTestStabilizerFactory
. This allows usingNgTestBed
without any dynamic
reflective factories (i.e.initReflector()
) and doesn't have impact to
most users.
Bug Fixes
-
Deleted an unnecessary
hostElement.append(componentRef.location)
. -
Fixed a bug where a
WillNeverStabilizeError
was thrown whenever there was
a non-zero lengthTimer
being executed. This was due to a bug in how the
NgStabilizer
was executing - constantly calling theupdate
function
instead of calling it once and waiting for stabilization. -
Fixed a bug where stabilizers are considered stable even when some of them
are not. -
Fixed a bug where
_createDynamic
does not preserverootInjector
. -
Added
NgTestBed.forComponent
, which takes aComponentFactory<T>
, and
optionally anInjectorFactory
. This allows writing tests entirely free of
any invocations ofinitReflector()
.
angular_router
2.0.0-alpha+19
- Maintenance release to support Angular 5.0.
angular_compiler
## 0.4.0
New Features
-
Added
TypedElement
to represent a statically parsedTyped
. -
TypedReader.parse()
now returns aTypedElement
. -
Added
$Typed
, aTypeChecker
forTyped
. -
Added
TypedReader
for parsing generic directive types. -
Added support for
void
andNull
types to appear in tokens. -
Added
DirectiveVisitor
, and removed$HostBinding
and$HostListener
. -
Added
ModuleReader.extractProviderObjects
to use in the view compiler. -
Added
logFine
as a new top-level API. -
Added an internal
cli.dart
library. Seelib/cli.dart
for details. -
Added
SplitDartEmitter
for internal use. -
Added
$QueryList
as aTypeChecker
. -
Expose the
$Provider
TypeChecker
. -
Added
typeArgumentOf
helper method. -
Added support for recognizing the
MultiToken
type. -
CompilerFlags
now supports as afast_boot
argument; default istrue
. -
ReflectorEmitter
now takes an optionaldeferredModules{Source}
. -
Started adding experimental support for a new
Module
syntax.
Breaking Changes
-
CompilerFlags
no longer parses and supports the'debug'
option and
genDebugInfo
is alwaysfalse
, and is deprecated pending removal in a
future version. -
Removes unused APIs of
ComponentReader
. -
TokenReader
no longer supports arbitrary const objects or literals. -
Removed
use_new_template_parser
flag. The old parser was removed. -
Removed
$QueryList
. -
Added
canRead
toNgAssetReader
. -
Moved
CompilerFlags
andProfile
tocli.dart
. -
linkToReference
now requires a second parameter, aLibraryReader
, and
treats private types (i.e. prefixed with_
) asdynamic
as the compiler
cannot point to them. -
ReflectableEmitter
has been completely replaced with a new implementation. -
Removed all references and use of determining a "prefix" of a type. This was
no longer used onceReflectableEmitter
was re-written. -
Removed a number of internal flags that were no longer strictly required.
-
ModuleReader.deduplicateProviders
now returns aList
not aSet
, and
providers that are multi are not removed, as it is a feature of the DI
system to have multiple of them with the same token. -
Add the
TypeLink
class, and replace uses ofUri
. -
@Component
and@Directive
annotated classes are no longer@Injectable
.
In practice this means they can no loger be provided as an implicitconst Provider(FooComponent)
without either manually adding@Injectable
or
refactoring your code. We found this didn't really affect users, and most
uses of components and directives in these lists were accidental.
Bug Fixes
-
Fixed a bug where the compiler crashed after resolving a bound type failed.
-
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. -
Fix a bug where
throwFailure
hit an NPE without a stack trace. -
linkTypeOf
correctly resolves bound types (i.e.<T>
) in most cases, and
can fallback todynamic
otherwise. -
Removed all remaining (invalid) references to
package:barback
. -
Prevented a
RangeError
that occurred when an invalid import lacked an
extension. -
ReflectorEmitter
now supportsMultiToken
and generic-typed tokens, with
some known limitations. See #782. -
Fix a bug in the outliner that did not the correct output extension.
angular_ast
0.5.6
- Maintence release to support
dart 2.0 stable
.