You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm logging this to document an additional use-case for this DEP and to double-check that the use-case is covered.
Angular 2 defines an annotation for users to specify which directives are used by a component. To illustrate, here's a simplified version:
// Defined by Angular 2classView {
finalList<Type> directives;
constView(this.directives);
}
The user uses this annotation as follows:
// User code@View(const [Foo, NgIf])
classMyComponent {}
Here the annotation means "I intend to use directives Foo and NgIf in MyComponent".
Problem
It turns out that the vast majority of components end up using NgIf, NgFor and other standard directives. Only very code size conscious users would want to hand pick every single directive for their component. We therefore would like to define two annotations, @BaseView and an extension of it @View. The latter would automatically include several popular directives so the user doesn't have to specify them. Here's how we would like to define them:
/// Use this if you want to specify every directive used by a component.classBaseView {
finalList<Type> directives;
constBaseView(this.directives);
}
/// Use this if you want to specify only non-standard directives. Standard/// directives are included by default.classViewextendsBaseView {
staticconstSTANDARD_DIRECTIVES=const [NgIf, NgFor, NgClass];
constView(List<Type> directives)
:super(const [STANDARD_DIRECTIVES, directives]);
}
The user would then use them as follows:
// User specifies _precisely_ what they want@BaseView(const [Foo, NgIf])
// User doesn't care much about extra size in JS output but// doesn't like boilerplate. It's ok include all common directives,// even though they only use some of them@View(const [Foo])
The catch
The catch is that the initializer list of View is invalid Dart, as it expects that View may be used in a non-const context. If I understand this DEP correctly, it addresses this problem by allowing the initializer list to be the following:
It would "inject" const into the list literal expression depending on whether the invocation is in a const context (which it is for annotations) or not.
Alternative: const class
A const class indicates that a class may only be instantiated as part of a const expression. new is not allowed. Here's how it would be declared:
Because the const modifier guarantees that the constructor is always invoked in a const context, it is safe to assume that directives constructor parameter is also a const value thus making the list literal expression valid.
The text was updated successfully, but these errors were encountered:
Could you just have the transformer or processor that's processing the @View annotations look for both @View and @BaseView and implicitly include those directives in the former? Does the @View annotation object itself actually need to store the standard directives in its list?
@munificent, there are some additional constraints:
Angular 2 can run in two modes: transformed and reflective. In reflective mode we get annotation data via mirrors. We would have to make both modes aware of @View and @BaseView. While not impossible, it would add some complexity to the code.
Angular 2 code is cross-transpiled to JS and Dart from a single source. In JS annotations become decorators which, being just chunks of imperative code attached to "targets" can do whatever they like (although at the expense of static analyzability). It would be undesirable to impose this constraint on JS API as it is capable of expressing collection composition in decorators.
We want to allow users to define their own extensions of Angular 2 annotations and add their own common directives. This means we would have to add more machinery to the transformer and to the reflection-mode code to support that.
I'm logging this to document an additional use-case for this DEP and to double-check that the use-case is covered.
Angular 2 defines an annotation for users to specify which directives are used by a component. To illustrate, here's a simplified version:
The user uses this annotation as follows:
Here the annotation means "I intend to use directives
Foo
andNgIf
inMyComponent
".Problem
It turns out that the vast majority of components end up using
NgIf
,NgFor
and other standard directives. Only very code size conscious users would want to hand pick every single directive for their component. We therefore would like to define two annotations,@BaseView
and an extension of it@View
. The latter would automatically include several popular directives so the user doesn't have to specify them. Here's how we would like to define them:The user would then use them as follows:
The catch
The catch is that the initializer list of
View
is invalid Dart, as it expects thatView
may be used in a non-const
context. If I understand this DEP correctly, it addresses this problem by allowing the initializer list to be the following:It would "inject"
const
into the list literal expression depending on whether the invocation is in aconst
context (which it is for annotations) or not.Alternative:
const class
A
const class
indicates that a class may only be instantiated as part of aconst
expression.new
is not allowed. Here's how it would be declared:Because the
const
modifier guarantees that the constructor is always invoked in aconst
context, it is safe to assume thatdirectives
constructor parameter is also aconst
value thus making the list literal expression valid.The text was updated successfully, but these errors were encountered: