AngularDart is a productive web application framework that powers some of Google's most critical applications. It's built on Dart and used extensively by Google AdWords, AdSense, Fiber, and many more projects.
Ramp up quickly with our docs, codelabs, and examples:
Go to Get Started for a quick introduction to creating and running AngularDart web apps.
Try the material design codelab, which uses the
angular_components
package for production-quality material design widgets built and used by
Google.
Follow the AngularDart tutorial to build a fully working application that includes routing, HTTP networking, and more.
You may also be interested in other codelabs and a set of community contributed tutorials.
The template parser no longer supports styles defined inside the template itself.
Previously, the following two snippets would have been parsed and shimmed in the same way.
<style> .my-class {padding: 10px;} </style>
@Component(
styles: ['.other-class {padding: 10px;}'],
)
class ExampleComponent{}
Now, only the latter will be parsed and shimmed. The former will be ignored.
The template parser no longer supports loading stylesheets defined in an
<link>
tag in the template itself.
Previously, the following two snippets would have loaded the exact same stylesheet.
<link href="my-styles.css" rel="stylesheet" />
@Component(
styleUrls: ['my-styles.css'],
)
class ExampleComponent {}
Now, only the latter will actually be loaded. The former will be ignored.
The deprecated field, ComponentRef.componentType
, which always threw, has
now been completely removed. This was a legacy field for older clients of
AngularDart.
Better error messages in the compiler by failing fast on all analyzer errors in element annotations (@Component, etc) and passing the analyzer error messages to the user.
Added runAfterChangesObserved
to NgZone
. This API is intended to be a
more precise way to execute code after AngularDart would have run change
detection (instead of relying on scheduleMicrotask
or Timer.run
).
Added new type-safe ways to use the Injector
API without dynamic calls:
void example(Injector injector) {
// Injecting "SomeType".
// Before:
var someType1 = injector.get(SomeType) as SomeType;
// After:
var someType2 = injector.provide<SomeType>();
// Injecting "OpaqueToken<SomeType>(...)".
// Before:
var someToken1 = injector.get(someToken) as SomeType;
// After:
var someToken2 = injector.provideToken(someToken);
}
The code in generated AppView
no longer performs null safety ?.
checks
when calling child views .destroy()
or .destroyNestedViews()
. This means
that misbehaving code could have slightly more confusing stack traces
(new null errors), at the benefit of reduced code-size across the board.
It's now a build error for @Component()
to include an entry in
directiveTypes
that types a directive not present in directives
.
#1653: AppView.lastRootNode
now correctly returns the last root node
when multiple ViewContainer
s are directly nested.
When using the @deferred
annotation in a template file, ensure that the
constructed component class uses the deferred import. For example, we now
emit deflib1.ComponentName(...)
instead of lib1.ComponentName(...)
. This
should ensure Dart2JS properly defer loads the entire component.
Typing a generic directive with a private type argument is now a build
error. Directive type arguments must be public so that they can be
referenced by the generated library that instantiates the directive.
Previously, this would build successfully but emit code that instantiated
the directive with dynamic
in place of the private type.
#1665: @Optional()
dependencies of pipes are now correctly treated as
optional. Previously the annotation was ignored, and attempting to
instantiate the pipe with a missing optional dependency would throw an error
for the missing dependency.
#1666: Properly emit calls from event bindings in templates where the tear-off function has one or more named arguments. Previously we would consider named arguments in the same vane as positional, and it would generate invalid code causing Dart2JS or DDC to fail compilation.
The @deferred
annotation now also defers the annotated component's
defining library, rather than just its generated template's library.
Added support for generic components and directives.
Type arguments can now be specified for any generic components and
directives via Typed
instances passed to the Component
annotation's
directiveTypes
parameter.
@Component(
selector: 'generic',
template: '{{value}}',
)
class GenericComponent<T> {
@Input()
T value;
}
@Component(
selector: 'example',
template: '''
<generic [value]="value"></generic>
''',
directives: [
GenericComponent,
],
directiveTypes: [
Typed<GenericComponent<String>>(),
],
)
class ExampleComponent {
var value = 'Hello generics!';
}
The Typed
class also has support for typing specific component and
directive instances by #
-reference, and flowing generic type parameters
from the annotated component as type arguments to its children. See its
documentation for details.
#930: Added @visibleForTemplate
to package:angular/meta.dart
. This
is an optional annotation that may be used to annotate elements that
should only be used from within generated code (i.e. a .template.dart
).
It is a compile-time hint, which may be treated as a failing build, to use
annotated elements outside of the component or template.
This annotation is intended to give component authors more control in
specifying the public API of their component(s), especially coupled with the
fact that AngularDart requires all members to be public to be reachable from
generated code. For example, c
and ngAfterChanges
are only accessible
from CalculatorComponent
(or its template) in the following:
import 'package:angular/angular.dart';
import 'package:angular/meta.dart';
@Component(
selector: 'calculator-comp',
template: '{{a}} + {{b}} = {{c}}',
)
class CalculatorComponent implements AfterChanges {
@Input()
num a = 0;
@Input()
num b = 0;
@visibleForTemplate
num c = 0;
@override
@visibleForTemplate
void ngAfterChanges() {
c = a + b;
}
}
NOTE: This feature is only enforced in SDK: >=2.1.0-dev.3.1
.
Added support for internationalization in templates.
The @i18n
annotation marks content in document fragments or attributes for
internationalization via integration with package:intl
.
A document fragment can be internationalized by applying the @i18n
annotation to its parent element:
<div @i18n="A description of the message.">
A message to be <i>translated</i>!
</div>
An attribute, property, or input <name>
can be internationalized by
applying the @i18n:<name>
annotation to its host element:
<input
placeholder="A message to be translated"
@i18n:placeholder="A description of the message.">
Note that internationalization in templates currently only supports messages with static text and HTML. See the example for more details.
#1538: A compile-time error is reported if the @deferred
template
annotation is present on a <template>
element or is a sibling to a
structural directive (such as *ngIf
). Before we would silently drop/ignore
the annotation, so this might be considered a breaking change of an
incorrect program. The fix is just to move the annotation, such as:
<!-- Before (Both are identical) -->
<template @deferred [ngIf]="showArea">
<expensive-comp></expensive-comp>
</template>
<expensive-comp *ngIf="showArea" @deferred></expensive-comp>
<!-- After (Both are identical) -->
<template [ngIf]="showArea">
<expensive-comp @deferred></expensive-comp>
</template>
<ng-container *ngIf="showArea">
<expensive-comp @deferred></expensive-comp>
</ng-container>
#1558: When importing a library.dart
that has two or more components
(i.e. Comp1
and Comp2
), and at least one component is used @deferred
and at least one component is used without @deferred
, the compiler would
generate invalid Dart code that would fail analysis/compilation to JS.
Correct code is now emitted, allowing the described scenario to work.
#1539: Fixed a bug where components that were @deferred
as the direct
child of another <template>
tag had phantom DOM left behind even after the
parent template was destroyed. For example:
<template [ngIf]="showComponent">
<expensive-comp @deferred></expensive-comp>
</template>
... additionally, a check for a race condition of the deferred component
being loaded after the parent view was already destroyed was added. As a
result, #1540 has also been fixed (view and content queries were not
getting reset as the @deferred
node was destroyed).
#880: Fixed a bug where an extraneous space in *ngFor
micro expression
caused the directive to no longer be functional (*ngFor="let x; let i =
$index "
, for example).
#1570: When a provider's token
for @GeneratedInjector(...)
is read
as null
(either intentionally, or due to analysis errors/imports missing)
a better error message is now thrown with the context of the error.
#434: In development mode, creating a component or service C
that
attempts to inject a missing dynamic dependency D
will now throw an error
message containing Could not find provider for D: C -> D
. Previously the
message was only Could not find provider for D
in these cases, which was
often not enough information to debug easily.
#1502: When parsing an invalid template micro expression (i.e.
*ngFor="let item of items;"
- note the trailing ;
), throws a proper
unexpected token error instead of a confusing type error during recovery.
#1500: Configuring a provider with FactoryProvider(Foo, null)
is now a
compile-time error, instead of a misleading runtime error.
#1591: Using @GenerateInjector
with a ValueProvider
bound to a
String
instance that expects a raw string (i.e r'$5.00'
) no longer
generates invalid code. Now all strings are emitted as raw.
#1598: Using @GenerateInjector
with a ValueProvider
whose value is
created as a const
object with named arguments is now created correctly.
Before, all named arguments were skipped (left to default values, which was
often null
).
@GenerateInjector(...)
now correctly solves duplicate tokens by having the
last, not first, provider win. This aligns the semantics with how the
other injector implementations work. For MultiToken
, the order stays the
same.
Clarified that Injector.map({...})
doesn't support null
as values.
Named arguments are now supported for function calls in templates where the
function is an exported symbol (Component(exports: [someFunction])
).
#1625: Named arguments in function calls in templates that collide with
an exported symbol (Component(exports: [someExport])
) no longer cause a
parsing error.
Whitespace in internationalized message descriptions and meanings is now normalized so they're no longer affected by formatting changes. Identical messages with meanings that are formatted differently will now properly be treated as the same message.
#1633: Using a function type or any non-class Type
inside of the
@GenerateInjector([...])
annotation would cause a non-ideal error to be
produced. It now includes more information where available.
Error ranges for invalid code sometimes listed the error offset as if it were a column on line 1. Now shows correct line and column number.
Error messages for misconfigured pipes now display their source location.
Assertion added for ensuring different SanitizationServices aren't used when calling runApp multiple times. SanitizationService is a static resource so different instances would not work as expected.
AppViewUtils.resetChangeDetection()
is now deprecated and will be removed
in the next major release.
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:
More details of changes to Dart 2 for web users are available on our website.
Thanks, and enjoy AngularDart!
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).
Provider
(and provide
) 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 it Provider<T>
.
ValueProvider(Type, T)
and ValueProvider.forToken(OpaqueToken<T>, T)
instead of Provider(typeOrToken, useValue: ...)
.
FactoryProvider(Type, T)
and FactoryProvider.forToken(OpaqueToken<T>,
T)
instead of Provider(typeOrToken, useFactory: ...)
.
ClassProvider(Type, useClass: T)
and
ClassProvider.forToken(OpaqueToken<T>, useClass: T)
instead of
Provider(typeOrToken, useClass: ...)
or an implicit Type
.
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 like String
. For example, you might use an OpaqueToken
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
deprecated multi: true
argument to the Provider
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) to extend
either OpaqueToken
or MultiToken
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
and MultiToken
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 of Injector
Function([Injector parent])
, was added and started to be used across the
framework. It normally indicates the ability to create a new Injector
instance with an optional parent.
A new annotation, @GenerateInjector
, was added. It is now posibble to
generate, at compile-time, a standalone InjectorFactory
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
of Provider
instances. This is an optional feature to use instead of
nested const
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 that include
is processed before provide
.
Module
rejects using a Type
implicitly as a ClassProvider
. This
removes additional ambiguity around supporting List<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
in ReflectiveInjector
:
// Using ReflectiveInjector is strongly not recommended for new code
// due to adverse effects on code-size and runtime performance.
final injector = ReflectiveInjector.resolveAndCreate([
commonModule,
]);
OpaqueToken
no longer overrides operator==
or hashCode
. In practice
this should have no effect for most programs, but it does mean that
effectively that only const
instances of OpaqueToken
(or MultiToken
)
are valid.
It is no longer valid to provide a token type of anything other than Type
or an OpaqueToken
(or MultiToken
). In the past anything from aribtrary
literals (such as a string - 'iAmAToken'
) or a custom const
instance of
a class were supported.
For defining whether a component or directive should provide itself for
injection, Visibility.none
has been renamed Visibility.local
to make it
more clear that it is accessable locally (within providers
for example).
Classes annotated with @Component
or @Directive
are no longer treated
like services annotated with @Injectable
, and not accessible (by default)
to ReflectiveInjector
. @Injectable
can always be added to these classes
in order to return to the old behavior.
Fixed a bug where calling get
on an Injector
injected in the context of
an @Component
or @Directive
-annotated class and passing a second
argument always returned null
(instead of that second argument) if the
token was not found.
Setting @Component(visibility: Visibility.none
) no longer applies to
providers
, if any. Note that Visibility.none
was always renamed
Visibility.local
in breaking changes above.
Fixed a bug where Provider(SomeType)
was not parsed correctly as an
implicit use of Provider(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 dependency Y
. We now emit the correct message.
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.
NgTemplateOutlet
added ngTemplateOutletContext
for setting local
variables in an embedded view. These variables are assignable to template
input variables declared using let
, which can be bound within the
template. See the NgTemplateOutlet
documentation for examples.
Added a lifecycle event AfterChanges
, which is similar to OnChanges
, 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
or HtmlElement
types from
content or view children instead of ElementRef
(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>
and List<HtmlElement>
for @ViewChildren
and @ContentChildren
no longer require read: 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 the const ['$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 type bool
, and adds an
attribute if true
, and removes it if false
and 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">
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))
.
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:
, and host:
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 now true
. 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 use runApp
(or runAppAsync
) to bootstrap the application without
relying on initReflector()
.
<ComponentRef>.componentType
always throws UnsupportedError
, 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 plain List
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 using Stream
and StreamController
.
COMMON_DIRECTIVES
was renamed commonDirectives
.
CORE_DIRECTIVES
was renamed coreDirectives
.
COMMON_PIPES
was renamed commonPipes
.
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.
SafeInnerHtmlDirective
is no longer injectable.
The following types were never intended for external use and are no longer
exported by package:angular/security.dart
:
SafeHtmlImpl
SafeScriptImpl
SafeStyleImpl
SafeResourceUrlImpl
SafeUrlImpl
SafeValueImpl
To mark a value as safe, users should inject DomSanitizationService
and
invoke the corresponding bypassSecurityTrust*()
method, instead of
constructing these types directly.
ComponentResolver
was removed, and SlowComponentLoader
was deprecated.
Methods in lifecycle hooks have void
return type. This is breaking change
if the override doesn't specify return type and uses return
without any
value. To fix add a void
or Future<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
and OnChanges
lifecycle interfaces. DoCheck
will never fill in values for the Map
in
OnChanges
, so this compile-error helps avoid bugs and directs the user to
use DoCheck
and AfterChanges
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).
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 the ExceptionHandler
.
Fixed a bug where DatePipe
didn't format millisecondsSinceEpoch
in the
local time zone (consistent with how it formats DateTime
).
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 always dynamic
), 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';
}
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
and ComponentRef
now have a generic type parameter
<T>
, which is properly reified where T
is the type of the component
class.
The $implicit
(iterable) value in *ngFor
is now properly typed whenever
possible. It was previously always typed as dynamic
, which caused dynamic
lookups/calls at runtime, and hid compilation errors.
The type of <EmbeddedViewRef>.rootNodes
and <ViewRefImpl>.rootNodes
has
been tightened from List<dynamic>
to List<Node>
(where Node
is from
dart:html
).
A combination of compile errors and warnings are produced when it seem that
template
, templateUrl
, style
, or styleUrls
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 as String
). 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 as final
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.
The process for starting your AngularDart application changed significantly:
runApp
function. Instead of starting your application by passing the Type
of
an @Component
-annotated class
, you now pass a ComponentFactory
,
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 generated InjectorFactory
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 the initReflector()
method or call, which is no longer needed.
That means using runApp
disables the use of SlowComponentLoader
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
and runAppLegacy
disables tree-shaking on any
class annotated with @Component
or @Injectable
. We strongly recommend
migrating to the runApp
pattern.
The top-level function bootstrap
was deleted. This function always threw a
runtime exception since 5.0.0-alpha+5
, and was a relic of when a code
transformer rewrote it automatically as bootstrapStatic
.
Dropped support for @AngularEntrypoint
and rewriting entrypoints to
automatically use initReflector()
and bootstrapStatic
. 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 the runAppAsync
or runAppLegacyAsync
functions with the
beforeComponentCreated
callback.
PlatformRef
and PlatformRefImpl
were removed.
package:angular/meta.dart
, a series of utilities for additional
static analysis checks and/or functions to retain semantics for migration
purposes, starting with castCallback1ForDirective
and
castCallback2ForDirective
. These methods are only intended to be used as
stop-gaps for the lack of generic support in AngularDart directives and
components. <NgZone>.onStable
has been renamed to onTurnDone
.
<NgZone>.onUnstable
has been renamed to onTurnStart
.
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's run()
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 (from Dart2JS
) going
forward to emit debug-only conditional code.
<ExceptionHandler>.call
with a null
exception.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.
@Pipe
-annotated classes are no longer considered @Injectable
, in that
they aren't usable within a ReflectiveInjector
. You can get this behavior
back by adding the @Injectable()
annotation to the @Pipe
-annotated
class. Similar changes are in progress for @Component
and @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 @Directive
or @Component
annotation.
Removed formDirectives
from COMMON_DIRECTIVES
list; replace
COMMON_DIRECTIVES
with [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 through package: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}
).
DynamicComponentLoader
was renamed SlowComponentLoader
to encourage
users to prefer ComponentLoader
. Additionally, arguments
projectableNodes:
and onDestroy:
callbacks were removed - they were
mostly unused, and confusing since they were undocumented.
Removed angular/platform/browser_static.dart
; replace imports with
angular/angular.dart
.
Removed angular/platform/common_dom.dart
; replace imports with
angular/angular.dart
.
Removed angular/testing.dart
; Use angular_test
package instead.
Removed angular/platform/testing.dart
.
Removed platform/testing/browser_static.dart
.
Removed MockNgZone
.
Removed ViewEncapsulation.native
, which is no longer supported.
Renamed FORM_DIRECTIVES
to formDirectives
.
Removed angular/common.dart
; replace imports with angular/angular.dart
.
Removed angular/compiler.dart
; compiler should only be invoked via the
transformers or via pkg:build
directly using angular/source_gen.dart
.
Deprecated @View()
annotation was completely removed.
Deprecated second parameter to ExceptionHandler
was 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.dart
was
also removed.
The bootstrap
function now always throws a runtime exception, and both it
and bootstrapStatic
are accessible via angular.dart
instead of
platform/browser.dart
and platform/browser_static.dart
#357.
Returning false
from an event handler will no longer cancel the event. See
#387 for details.
Removed Query
and ViewQuery
. Please use ContentChild
/ContentChildren
and ViewChild
/ViewChildren
in their place instead.
Removed the use_analyzer
flag for the transformer. This is always true
.
#404.
Removed all other unused or unsupported flags from the transformer. There is
now a single CompilerFlags
class 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 outputs
field from Directive
. Outputs now must be declared using
inline Output
annotations.
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 selector
and providers
parameters 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();
}
visibility
property to Directive
. Directives and components that
don't need to be injected can set visibility: Visibility.none
in 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 { ... }
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. ComponentLoader
is 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
's Element
or HtmlElement
instead
of ElementRef
, which is "soft deprecated" (will be deprecated and removed
in a future release).
findContainer
has now been exposed from NgForm allowing easier creation of
custom form implementations.
setUpControl
has 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 {}
bool
now receive a default value of true
instead
of a value of null
or 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;
}
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:
const
(not final
) can be exported. Added @deferred
as the first "compile-time" directive (it has no specific
runtime code nor is it listed in a directives: [ ... ]
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-sync
branch for what has yet to be
merged into master
.
We no longer emit ng_*.json
files 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.
/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-deep
is a drop-in
replacement, intended to provide the same functionality as /deep/
and
>>>
, without the need to use deprecated or unsupported CSS syntax
#454.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 ngSwitch
behavior in Dartium.
Fixed a bug in @deferred
when nested views has DI bindings. Fixes
#578.
The transformer now fails if any unsupported arguments are passed in.
Fixed a bug where @deferred
did not work nested inside of <template>
:
<template [ngIf]="someCondition">
<expensive-comp @deferred></expensive-comp>
</template>
ngForm
now allows onSubmit
to be called with a null
value.
Using inputs|outputs
in the @Component
annotation to rename an existing
@Input()
or @Output()
now logs and fails the build during compilation.
Symbol collisions with dart:html
no longer cause a runtime exception, all
framework use of dart:html
is now scoped behind a prefixed import.
Properly annotate methods in generated .template.dart
code with
@override
.
Updated the documentation for OnInit
and OnDestroy
to mention more
specifics about the contract and document "crash detection" cases where they
may be called more than once.
*ngIf
now properly checks that inputs do not change during change
detection #453.
Properly typed TrackByFn
as an int
not a num
#431.
Import aliases are supported by the compiler #245.
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#detectHostChanges
method.
Introduced a new AppViewData
structure 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 final
property reads.
Some of the enums used to manage change detection state have been simplified
to int
in order to reduce the cost in the generated code.
Exposed TouchFunction
and ChangeFunction
typedefs 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.
dart:mirrors
(i.e. running AngularDart without code generation) is
now formally deprecated. In 4.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.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 throwOnChanges
checks outside of dev-mode.
interpolate
is now represented by multiple functions (faster).KeyValueDiffer
(NgClass
, NgStyle
) optimized for initial add/removals.composeValidators
and composeAsyncValidators
now part of the public API.angular2/testing.dart
includes a test-only isDebugMode
function.AbstractControl.markAsDirty
now emits a status change event. Requires at least Dart SDK 1.23.0
.
Injecting null
is no longer supported.
Remove unused useProperty
argument in DI Provider
api.
ReflectionCapabilities.isReflectionEnabled
renamed to reflectionEnabled
.
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, use dart:html
:
document.title = 'My title';
DynamicComponentLoader
now has a simplified API:
loadAsRoot
, loadAsRootIntoNode
replaced by a single load
method that
always creates the component root node instead of hoisting into an existing
node.
Removed viewBindings
from Component
. This has been interchangeable with
viewProviders
for a while now.
BEFORE: dart @Component(viewBindings: const [])
AFTER: dart @Component(viewProviders: const [])
Removed EventManager
from the public API. Code generation is now closer to
document.addEventListener
and having this interception layer would not
allow further optimizations.
Removed IterableDifferFactory
and KeyValueDifferFactory
from the public
API. We have planned compiler optimizations that will no longer allow
overriding our diffing implementations. Looking into alternatives before a
final 3.0.0
release that are lower cost.
ASYNC_VALIDATORS
can no longer return a Stream
instance, only Future
.
The experimental NgTestBed
was removed. Use package:angular_test
now.
By default, the ExceptionHandler
is a BrowserExceptionHandler
, which
prints exceptions to the console. If you don't want this behavior (i.e.
releasing to production), make sure to override it.
ElementRef.nativeElement
is now final
(no setter).
DOM adapter is now completely removed from the API and generated code
A name
parameter is now required for all @Pipe(...)
definitions:
BEFORE: dart @Pipe(name: 'uppercase')
AFTER: dart @Pipe('uppercase')
DomEventsPlugin
now requires a strongly typed interface to dart:html
.
Null
is 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 of SimpleChange
. Instead, check
whether previousValue
is null
.
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 clickHandler
is null
during initialization.
@Component(
selector: 'my-component',
template: '<div (click)="clickHandler($event)"></div>')
class MyComponent {
Function clickHandler;
}
Removed Component.moduleId
, which was unused.
@View
will be removed in 4.0
, only use @Component
instead.EventEmitter
is now @Deprecated
: Use Stream
and StreamController
.ngSwitchCase
replaces ngSwitchWhen
(soft deprecation).XHR
is deprecated, along with the runtime/reflective compiler.IterableDiffers
and KeyValueDiffers
are 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.<ng-content select="...">
does not emit incorrect code (regression).ngSwitchWhen
now properly compares identity in Dartium.Component/Directive#selector
is now a @required
property.ngIf
now throws again if the bound value changes during change detection.AppView<...>
.Pipe
s..template.dart
file.NgControl
, valueAccessor
no longer can throw an
NPEstrong-mode
analysis within the project, and fixed some errors.<T>
generic type syntax for methods, not /*<T>*/
.NgZoneImpl
, all the code exists in NgZone
now.AppView
..template.dart
change detected primitives are typed.renderType
as a static class member in generated code.@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.BEFORE ```dart class MyComponent { QueryList<ChildComponent> _childComponents;
MyComponent(@ContentChildren(ChildComponent) this._childComponents); } ```
AFTER ```dart class MyComponent { QueryList<ChildComponent> _childComponents;
@ContentChildren(ChildComponent) set childComponents(QueryList<ChildComponent> childComponents) { _childComponents = childComponents; } } ```
angular2/reflection.dart
now works properly.angular2/reflection.dart
as canonical way to opt-in to mirrors.
In 2.2.0 it will be considered deprecated to enable runtime reflection by
any other means.NgControlStatus
no longer included in COMMON_DIRECTIVES
and in
FORM_DIRECTIVES
. Needs to be manually included in your bootstrap or
migrated off of@Query
in a component constructor; move to field-levelRenderer
: Use dart:html
directlyNgControlStatus
: A form control should set class they are interested
inNgPlural
: Was never formally supported in Angular Dart. Recommend
using package:intl
with getters on your @Component
pointing to an
Intl.message
call until we have formal template support (planned)ObservableListDiff
: Not properly implemented, will re-introduce laterInjectorModule
- was never formally supportedInjectorModule
code (from TS-transpiler era)ExceptionHandler
not being called during change detectionobservable
package, instead of observe
.Renderer.createViewRoot
.pkg/build
..analysis_options
to enforce a number of style rules.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.
This is the first release of Angular 2 for Dart that is written directly in Dart, instead of generated from TypeScript.
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)
el
.Add this to your package's pubspec.yaml file:
dependencies:
angular: ^5.2.0
You can install packages from the command line:
with pub:
$ pub get
Alternatively, your editor might support pub get
.
Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:angular/angular.dart';
Version | Uploaded | Documentation | Archive |
---|---|---|---|
5.2.0 | Dec 10, 2018 |
|
|
5.1.0 | Oct 10, 2018 |
|
|
5.0.0 | Aug 7, 2018 |
|
|
4.0.0+2 | Jan 9, 2018 |
|
|
4.0.0+1 | Dec 7, 2017 |
|
|
4.0.0 | Aug 30, 2017 |
|
|
1.1.2+2 | Oct 14, 2015 |
|
|
1.1.2 | Apr 28, 2015 |
|
|
1.1.1 | Apr 1, 2015 |
|
|
1.1.0 | Jan 16, 2015 |
|
|
Popularity:
Describes how popular the package is relative to other packages.
[more]
|
98
|
Health:
Code health derived from static analysis.
[more]
|
90
|
Maintenance:
Reflects how tidy and up-to-date the package is.
[more]
|
70
|
Overall:
Weighted score of the above.
[more]
|
90
|
We analyzed this package on Feb 20, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:
Detected platforms: web
Primary library:
package:angular/angular.dart
with components:html
,js
.
Fix lib/src/core/linker/view_container.dart
. (-1.99 points)
Analysis of lib/src/core/linker/view_container.dart
reported 4 hints:
line 26 col 3: 'ElementRef' is deprecated and shouldn't be used.
line 32 col 3: 'ElementRef' is deprecated and shouldn't be used.
line 32 col 48: 'ElementRef' is deprecated and shouldn't be used.
line 51 col 3: 'ElementRef' is deprecated and shouldn't be used.
Fix lib/src/bootstrap/run.dart
. (-1.49 points)
Analysis of lib/src/bootstrap/run.dart
reported 3 hints:
line 10 col 42: 'SlowComponentLoader' is deprecated and shouldn't be used.
line 290 col 11: 'SlowComponentLoader' is deprecated and shouldn't be used.
line 332 col 11: 'SlowComponentLoader' is deprecated and shouldn't be used.
Fix lib/experimental.dart
. (-1 points)
Analysis of lib/experimental.dart
reported 2 hints:
line 44 col 7: 'SlowComponentLoader' is deprecated and shouldn't be used.
line 44 col 34: 'SlowComponentLoader' is deprecated and shouldn't be used.
Fix additional 9 files with analysis or formatting issues. (-6 points)
Additional issues in the following files:
lib/src/common/common_directives.dart
(2 hints)lib/src/compiler/view_compiler/compile_view.dart
(2 hints)lib/src/source_gen/template_compiler/compile_metadata.dart
(2 hints)lib/angular.dart
(1 hint)lib/src/common/directives.dart
(1 hint)lib/src/core/linker.dart
(1 hint)lib/src/core/linker/template_ref.dart
(1 hint)lib/src/core/linker/view_container_ref.dart
(1 hint)lib/src/source_gen/template_compiler/find_components.dart
(1 hint)The package description is too short. (-20 points)
Add more detail to the description
field of pubspec.yaml
. Use 60 to 180 characters to describe the package, what it does, and its target use case.
Maintain an example. (-10 points)
Create a short demo in the example/
directory to show how to use this package.
Common filename patterns include main.dart
, example.dart
, and angular.dart
. Packages with multiple examples should provide example/README.md
.
For more information see the pub package layout conventions.
Package | Constraint | Resolved | Available |
---|---|---|---|
Direct dependencies | |||
Dart SDK | >=2.1.0-dev.5.0 <3.0.0 | ||
analyzer | ^0.34.0 | 0.34.3 | 0.35.1 |
angular_ast | 0.5.8 | 0.5.8 | |
angular_compiler | 0.4.2 | 0.4.2 | |
build | >=0.12.7 <2.0.0 | 1.1.0 | 1.1.1 |
build_config | >=0.2.6 <0.4.0 | 0.3.1+4 | |
code_builder | ^3.0.1 | 3.2.0 | |
collection | ^1.14.5 | 1.14.11 | |
csslib | ^0.14.5 | 0.14.6 | |
intl | >=0.13.0 <0.16.0 | 0.15.7 | |
js | ^0.6.0 | 0.6.1+1 | |
logging | >=0.9.0 <0.12.0 | 0.11.3+2 | |
meta | ^1.1.4 | 1.1.7 | |
path | ^1.6.1 | 1.6.2 | |
source_gen | >=0.9.1 <0.10.0 | 0.9.4+1 | |
source_span | ^1.4.0 | 1.5.4 | |
stack_trace | ^1.9.1 | 1.9.3 | |
Transitive dependencies | |||
args | 1.5.1 | ||
async | 2.0.8 | ||
built_collection | 4.1.0 | ||
built_value | 6.3.0 | ||
charcode | 1.1.2 | ||
convert | 2.1.1 | ||
crypto | 2.0.6 | ||
dart_style | 1.2.3 | ||
fixnum | 0.10.9 | ||
front_end | 0.1.9+1 | 0.1.11 | |
glob | 1.1.7 | ||
html | 0.13.3+3 | ||
json_annotation | 2.0.0 | ||
kernel | 0.3.9+1 | 0.3.11 | |
matcher | 0.12.4 | ||
package_config | 1.0.5 | ||
plugin | 0.2.0+3 | ||
pub_semver | 1.4.2 | ||
pubspec_parse | 0.1.4 | ||
quiver | 2.0.1 | ||
string_scanner | 1.0.4 | ||
term_glyph | 1.1.0 | ||
typed_data | 1.1.6 | ||
utf | 0.9.0+5 | ||
watcher | 0.9.7+10 | ||
yaml | 2.1.15 |