parent
f13f4db9dc
commit
2fee5cc095
|
@ -14,7 +14,7 @@ export {
|
|||
detectChanges as ɵdetectChanges,
|
||||
renderComponent as ɵrenderComponent,
|
||||
ComponentType as ɵComponentType,
|
||||
inject as ɵinject,
|
||||
directiveInject as ɵdirectiveInject,
|
||||
injectTemplateRef as ɵinjectTemplateRef,
|
||||
injectViewContainerRef as ɵinjectViewContainerRef,
|
||||
injectChangeDetectorRef as ɵinjectChangeDetectorRef,
|
||||
|
|
|
@ -47,7 +47,6 @@ export function defineComponent<T>(componentDefinition: ComponentDefArgs<T>): Co
|
|||
inputs: invertObject(componentDefinition.inputs),
|
||||
inputsPropertyName: componentDefinition.inputsPropertyName || null,
|
||||
outputs: invertObject(componentDefinition.outputs),
|
||||
methods: invertObject(componentDefinition.methods),
|
||||
rendererType: resolveRendererType2(componentDefinition.rendererType) || null,
|
||||
exportAs: componentDefinition.exportAs,
|
||||
onInit: type.prototype.ngOnInit || null,
|
||||
|
|
|
@ -174,7 +174,7 @@ export function diPublic(def: DirectiveDef<any>): void {
|
|||
}
|
||||
|
||||
/**
|
||||
* Searches for an instance of the given directive type up the injector tree and returns
|
||||
* Searches for an instance of the given type up the injector tree and returns
|
||||
* that instance if found.
|
||||
*
|
||||
* If not found, it will propagate up to the next parent injector until the token
|
||||
|
@ -187,15 +187,18 @@ export function diPublic(def: DirectiveDef<any>): void {
|
|||
*
|
||||
* static ngDirectiveDef = defineDirective({
|
||||
* type: SomeDirective,
|
||||
* factory: () => new SomeDirective(inject(DirectiveA))
|
||||
* factory: () => new SomeDirective(directiveInject(DirectiveA))
|
||||
* });
|
||||
* }
|
||||
*
|
||||
* NOTE: use `directiveInject` with `@Directive`, `@Component`, and `@Pipe`. For
|
||||
* all other injection use `inject` which does not walk the DOM render tree.
|
||||
*
|
||||
* @param token The directive type to search for
|
||||
* @param flags Injection flags (e.g. CheckParent)
|
||||
* @returns The instance found
|
||||
*/
|
||||
export function inject<T>(token: Type<T>, flags?: InjectFlags, defaultValue?: T): T {
|
||||
export function directiveInject<T>(token: Type<T>, flags?: InjectFlags, defaultValue?: T): T {
|
||||
return getOrCreateInjectable<T>(getOrCreateNodeInjector(), token, flags, defaultValue);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import {NgOnChangesFeature, PublicFeature, defineComponent, defineDirective, def
|
|||
import {InjectFlags} from './di';
|
||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveType} from './interfaces/definition';
|
||||
|
||||
export {InjectFlags, QUERY_READ_CONTAINER_REF, QUERY_READ_ELEMENT_REF, QUERY_READ_FROM_NODE, QUERY_READ_TEMPLATE_REF, inject, injectAttribute, injectChangeDetectorRef, injectElementRef, injectTemplateRef, injectViewContainerRef} from './di';
|
||||
export {InjectFlags, QUERY_READ_CONTAINER_REF, QUERY_READ_ELEMENT_REF, QUERY_READ_FROM_NODE, QUERY_READ_TEMPLATE_REF, directiveInject, injectAttribute, injectChangeDetectorRef, injectElementRef, injectTemplateRef, injectViewContainerRef} from './di';
|
||||
export {CssSelector} from './interfaces/projection';
|
||||
|
||||
|
||||
|
|
|
@ -8,10 +8,13 @@
|
|||
|
||||
import {ChangeDetectionStrategy} from '../../change_detection/constants';
|
||||
import {PipeTransform} from '../../change_detection/pipe_transform';
|
||||
import {Provider} from '../../core';
|
||||
import {RendererType2} from '../../render/api';
|
||||
import {Type} from '../../type';
|
||||
import {resolveRendererType2} from '../../view/util';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Definition of what a template rendering function should look like.
|
||||
*/
|
||||
|
@ -19,16 +22,37 @@ export type ComponentTemplate<T> = {
|
|||
(ctx: T, creationMode: boolean): void; ngPrivateData?: never;
|
||||
};
|
||||
|
||||
/**
|
||||
* A subclass of `Type` which has a static `ngComponentDef`:`ComponentDef` field making it
|
||||
* consumable for rendering.
|
||||
*/
|
||||
export interface ComponentType<T> extends Type<T> { ngComponentDef: ComponentDef<T>; }
|
||||
|
||||
/**
|
||||
* A subclass of `Type` which has a static `ngDirectiveDef`:`DirectiveDef` field making it
|
||||
* consumable for rendering.
|
||||
*/
|
||||
export interface DirectiveType<T> extends Type<T> { ngDirectiveDef: DirectiveDef<T>; }
|
||||
|
||||
export const enum DirectiveDefFlags {ContentQuery = 0b10}
|
||||
|
||||
/**
|
||||
* A subclass of `Type` which has a static `ngPipeDef`:`PipeDef` field making it
|
||||
* consumable for rendering.
|
||||
*/
|
||||
export interface PipeType<T> extends Type<T> { ngPipeDef: PipeDef<T>; }
|
||||
|
||||
/**
|
||||
* `DirectiveDef` is a compiled version of the Directive used by the renderer instructions.
|
||||
* Runtime link information for Directives.
|
||||
*
|
||||
* This is internal data structure used by the render to link
|
||||
* directives into templates.
|
||||
*
|
||||
* NOTE: Always use `defineDirective` function to create this object,
|
||||
* never create the object directly since the shape of this object
|
||||
* can change between versions.
|
||||
*
|
||||
* See: {@link defineDirective}
|
||||
*/
|
||||
export interface DirectiveDef<T> {
|
||||
/** Token representing the directive. Used by DI. */
|
||||
|
@ -59,11 +83,6 @@ export interface DirectiveDef<T> {
|
|||
*/
|
||||
readonly outputs: {[P in keyof T]: P};
|
||||
|
||||
/**
|
||||
* A dictionary mapping the methods' minified names to their original unminified ones.
|
||||
*/
|
||||
readonly methods: {[P in keyof T]: P};
|
||||
|
||||
/**
|
||||
* Name under which the directive is exported (for use with local references in template)
|
||||
*/
|
||||
|
@ -104,6 +123,18 @@ export interface DirectiveDef<T> {
|
|||
onDestroy: (() => void)|null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime link information for Components.
|
||||
*
|
||||
* This is internal data structure used by the render to link
|
||||
* components into templates.
|
||||
*
|
||||
* NOTE: Always use `defineComponent` function to create this object,
|
||||
* never create the object directly since the shape of this object
|
||||
* can change between versions.
|
||||
*
|
||||
* See: {@link defineComponent}
|
||||
*/
|
||||
export interface ComponentDef<T> extends DirectiveDef<T> {
|
||||
/**
|
||||
* The tag name which should be used by the component.
|
||||
|
@ -128,10 +159,31 @@ export interface ComponentDef<T> extends DirectiveDef<T> {
|
|||
|
||||
/** Whether or not this component's ChangeDetectionStrategy is OnPush */
|
||||
readonly onPush: boolean;
|
||||
|
||||
/**
|
||||
* Defines the set of injectable providers that are visible to a Directive and its content DOM
|
||||
* children.
|
||||
*/
|
||||
readonly providers?: Provider[];
|
||||
|
||||
/**
|
||||
* Defines the set of injectable providers that are visible to a Directive and its view DOM
|
||||
* children only.
|
||||
*/
|
||||
readonly viewProviders?: Provider[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime link information for Pipes.
|
||||
*
|
||||
* This is internal data structure used by the renderer to link
|
||||
* pipes into templates.
|
||||
*
|
||||
* NOTE: Always use `definePipe` function to create this object,
|
||||
* never create the object directly since the shape of this object
|
||||
* can change between versions.
|
||||
*
|
||||
* See: {@link definePipe}
|
||||
*/
|
||||
export interface PipeDef<T> {
|
||||
/**
|
||||
|
@ -154,30 +206,142 @@ export interface PipeDef<T> {
|
|||
onDestroy: (() => void)|null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Arguments for `defineDirective`
|
||||
*/
|
||||
export interface DirectiveDefArgs<T> {
|
||||
/**
|
||||
* Directive type, needed to configure the injector.
|
||||
*/
|
||||
type: Type<T>;
|
||||
|
||||
/**
|
||||
* Factory method used to create an instance of directive.
|
||||
*/
|
||||
factory: () => T | [T];
|
||||
|
||||
/**
|
||||
* Static attributes to set on host element.
|
||||
*
|
||||
* Even indices: attribute name
|
||||
* Odd indices: attribute value
|
||||
*/
|
||||
attributes?: string[];
|
||||
|
||||
/**
|
||||
* A map of input names.
|
||||
*
|
||||
* The format is in: `{[actualPropertyName: string]:string}`.
|
||||
*
|
||||
* Which the minifier may translate to: `{[minifiedPropertyName: string]:string}`.
|
||||
*
|
||||
* This allows the render to re-construct the minified and non-minified names
|
||||
* of properties.
|
||||
*/
|
||||
inputs?: {[P in keyof T]?: string};
|
||||
|
||||
/**
|
||||
* TODO: Remove per https://github.com/angular/angular/issues/22591
|
||||
*/
|
||||
inputsPropertyName?: {[P in keyof T]?: string};
|
||||
|
||||
/**
|
||||
* A map of output names.
|
||||
*
|
||||
* The format is in: `{[actualPropertyName: string]:string}`.
|
||||
*
|
||||
* Which the minifier may translate to: `{[minifiedPropertyName: string]:string}`.
|
||||
*
|
||||
* This allows the render to re-construct the minified and non-minified names
|
||||
* of properties.
|
||||
*/
|
||||
outputs?: {[P in keyof T]?: string};
|
||||
methods?: {[P in keyof T]?: string};
|
||||
|
||||
/**
|
||||
* A list of optional features to apply.
|
||||
*
|
||||
* See: {@link NgOnChangesFeature}, {@link PublicFeature}
|
||||
*/
|
||||
features?: DirectiveDefFeature[];
|
||||
|
||||
/**
|
||||
* Function executed by the parent template to allow child directive to apply host bindings.
|
||||
*/
|
||||
hostBindings?: (directiveIndex: number, elementIndex: number) => void;
|
||||
|
||||
/**
|
||||
* Defines the name that can be used in the template to assign this directive to a variable.
|
||||
*
|
||||
* See: {@link Directive.exportAs}
|
||||
*/
|
||||
exportAs?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Arguments for `defineComponent`.
|
||||
*/
|
||||
export interface ComponentDefArgs<T> extends DirectiveDefArgs<T> {
|
||||
/**
|
||||
* HTML tag name to use in place where this component should be instantiated.
|
||||
*/
|
||||
tag: string;
|
||||
|
||||
/**
|
||||
* Template function use for rendering DOM.
|
||||
*
|
||||
* This function has following structure.
|
||||
*
|
||||
* ```
|
||||
* function Template<T>(ctx:T, creationMode: boolean) {
|
||||
* if (creationMode) {
|
||||
* // Contains creation mode instructions.
|
||||
* }
|
||||
* // Contains binding update instructions
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Common instructions are:
|
||||
* Creation mode instructions:
|
||||
* - `elementStart`, `elementEnd`
|
||||
* - `text`
|
||||
* - `container`
|
||||
* - `listener`
|
||||
*
|
||||
* Binding update instructions:
|
||||
* - `bind`
|
||||
* - `elementAttribute`
|
||||
* - `elementProperty`
|
||||
* - `elementClass`
|
||||
* - `elementStyle`
|
||||
*
|
||||
*/
|
||||
template: ComponentTemplate<T>;
|
||||
|
||||
/**
|
||||
* A list of optional features to apply.
|
||||
*
|
||||
* See: {@link NgOnChancesFeature}, {@link PublicFeature}
|
||||
*/
|
||||
features?: ComponentDefFeature[];
|
||||
|
||||
rendererType?: RendererType2;
|
||||
|
||||
changeDetection?: ChangeDetectionStrategy;
|
||||
|
||||
/**
|
||||
* Defines the set of injectable objects that are visible to a Directive and its light DOM
|
||||
* children.
|
||||
*/
|
||||
providers?: Provider[];
|
||||
|
||||
/**
|
||||
* Defines the set of injectable objects that are visible to its view DOM children.
|
||||
*/
|
||||
viewProviders?: Provider[];
|
||||
}
|
||||
|
||||
export type DirectiveDefFeature = <T>(directiveDef: DirectiveDef<T>) => void;
|
||||
export type ComponentDefFeature = <T>(directiveDef: DirectiveDef<T>) => void;
|
||||
export type ComponentDefFeature = <T>(componentDef: ComponentDef<T>) => void;
|
||||
|
||||
// Note: This hack is necessary so we don't erroneously get a circular dependency
|
||||
// failure based on types.
|
||||
|
|
|
@ -10,7 +10,7 @@ import {NgForOf as NgForOfDef} from '@angular/common';
|
|||
import {IterableDiffers} from '@angular/core';
|
||||
|
||||
import {defaultIterableDiffers} from '../../src/change_detection/change_detection';
|
||||
import {DirectiveType, InjectFlags, NgOnChangesFeature, defineDirective, inject, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
||||
import {DirectiveType, InjectFlags, NgOnChangesFeature, defineDirective, directiveInject, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
||||
|
||||
export const NgForOf: DirectiveType<NgForOfDef<any>> = NgForOfDef as any;
|
||||
|
||||
|
@ -18,7 +18,7 @@ NgForOf.ngDirectiveDef = defineDirective({
|
|||
type: NgForOfDef,
|
||||
factory: () => new NgForOfDef(
|
||||
injectViewContainerRef(), injectTemplateRef(),
|
||||
inject(IterableDiffers, InjectFlags.Default, defaultIterableDiffers)),
|
||||
directiveInject(IterableDiffers, InjectFlags.Default, defaultIterableDiffers)),
|
||||
features: [NgOnChangesFeature],
|
||||
inputs: {
|
||||
ngForOf: 'ngForOf',
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import {Component, ContentChild, Directive, Injectable, Injector, Input, NgModule, NgModuleFactory, NgModuleRef, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef} from '../../../src/core';
|
||||
import * as r3 from '../../../src/render3/index';
|
||||
|
||||
import {pending_pull_22005} from './small_app_spec';
|
||||
import {$pending_pr_22458$} from './pending_api_spec';
|
||||
|
||||
const details_elided = {
|
||||
type: Object,
|
||||
|
@ -60,7 +60,7 @@ export class LibBComponent {
|
|||
@NgModule({declarations: [LibAComponent], imports: []})
|
||||
export class LibBModule {
|
||||
// COMPILER GENERATED
|
||||
static ngInjectorDef = pending_pull_22005.defineInjector(details_elided);
|
||||
static ngInjectorDef = $pending_pr_22458$.defineInjector(details_elided);
|
||||
}
|
||||
// END FILE: node_modules/libB/module.ts
|
||||
// BEGIN FILE: node_modules/libB/module.metadata.json
|
||||
|
@ -92,7 +92,7 @@ export class AppComponent {
|
|||
@NgModule({declarations: [LibAComponent], imports: []})
|
||||
export class AppModule {
|
||||
// COMPILER GENERATED
|
||||
static ngInjectorDef = pending_pull_22005.defineInjector(details_elided);
|
||||
static ngInjectorDef = $pending_pr_22458$.defineInjector(details_elided);
|
||||
}
|
||||
// END FILE: src/app.ts
|
||||
|
||||
|
@ -113,7 +113,7 @@ function ngBackPatch_node_modules_libB_module_LibAComponent() {
|
|||
}
|
||||
|
||||
function ngBackPatch_node_modules_libB_module_LibAModule() {
|
||||
(LibAModule as any).ngInjectorDef = pending_pull_22005.defineInjector(details_elided);
|
||||
(LibAModule as any).ngInjectorDef = $pending_pr_22458$.defineInjector(details_elided);
|
||||
}
|
||||
|
||||
export const AppModuleFactory: NgModuleFactory<AppModule>&{patchedDeps: boolean} = {
|
||||
|
|
|
@ -6,103 +6,194 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core';
|
||||
import {Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Inject, InjectFlags, Injectable, Injector, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, SkipSelf, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core';
|
||||
import * as $r3$ from '../../../src/core_render3_private_export';
|
||||
import {renderComponent, toHtml} from '../render_util';
|
||||
|
||||
import {$pending_pr_22458$} from './pending_api_spec';
|
||||
|
||||
|
||||
|
||||
/// See: `normative.md`
|
||||
describe('injection', () => {
|
||||
type $boolean$ = boolean;
|
||||
|
||||
it('should inject ChangeDetectorRef', () => {
|
||||
type $MyComp$ = MyComp;
|
||||
type $MyApp$ = MyApp;
|
||||
describe('directives', () => {
|
||||
// Directives (and Components) should use `directiveInject`
|
||||
it('should inject ChangeDetectorRef', () => {
|
||||
type $MyComp$ = MyComp;
|
||||
type $MyApp$ = MyApp;
|
||||
|
||||
@Component({selector: 'my-comp', template: `{{ value }}`})
|
||||
class MyComp {
|
||||
value: string;
|
||||
constructor(public cdr: ChangeDetectorRef) { this.value = (cdr.constructor as any).name; }
|
||||
@Component({selector: 'my-comp', template: `{{ value }}`})
|
||||
class MyComp {
|
||||
value: string;
|
||||
constructor(public cdr: ChangeDetectorRef) { this.value = (cdr.constructor as any).name; }
|
||||
|
||||
// NORMATIVE
|
||||
static ngComponentDef = $r3$.ɵdefineComponent({
|
||||
type: MyComp,
|
||||
tag: 'my-comp',
|
||||
factory: function MyComp_Factory() { return new MyComp($r3$.ɵinjectChangeDetectorRef()); },
|
||||
template: function MyComp_Template(ctx: $MyComp$, cm: $boolean$) {
|
||||
if (cm) {
|
||||
$r3$.ɵT(0);
|
||||
// NORMATIVE
|
||||
static ngComponentDef = $r3$.ɵdefineComponent({
|
||||
type: MyComp,
|
||||
tag: 'my-comp',
|
||||
factory: function MyComp_Factory() {
|
||||
return new MyComp($r3$.ɵinjectChangeDetectorRef());
|
||||
},
|
||||
template: function MyComp_Template(ctx: $MyComp$, cm: $boolean$) {
|
||||
if (cm) {
|
||||
$r3$.ɵT(0);
|
||||
}
|
||||
$r3$.ɵt(0, $r3$.ɵb(ctx.value));
|
||||
}
|
||||
$r3$.ɵt(0, $r3$.ɵb(ctx.value));
|
||||
}
|
||||
});
|
||||
// /NORMATIVE
|
||||
}
|
||||
});
|
||||
// /NORMATIVE
|
||||
}
|
||||
|
||||
class MyApp {
|
||||
static ngComponentDef = $r3$.ɵdefineComponent({
|
||||
type: MyApp,
|
||||
tag: 'my-app',
|
||||
factory: function MyApp_Factory() { return new MyApp(); },
|
||||
/** <my-comp></my-comp> */
|
||||
template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) {
|
||||
if (cm) {
|
||||
$r3$.ɵE(0, MyComp);
|
||||
$r3$.ɵe();
|
||||
class MyApp {
|
||||
static ngComponentDef = $r3$.ɵdefineComponent({
|
||||
type: MyApp,
|
||||
tag: 'my-app',
|
||||
factory: function MyApp_Factory() { return new MyApp(); },
|
||||
/** <my-comp></my-comp> */
|
||||
template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) {
|
||||
if (cm) {
|
||||
$r3$.ɵE(0, MyComp);
|
||||
$r3$.ɵe();
|
||||
}
|
||||
MyComp.ngComponentDef.h(1, 0);
|
||||
$r3$.ɵr(1, 0);
|
||||
}
|
||||
MyComp.ngComponentDef.h(1, 0);
|
||||
$r3$.ɵr(1, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const app = renderComponent(MyApp);
|
||||
// ChangeDetectorRef is the token, ViewRef is historically the constructor
|
||||
expect(toHtml(app)).toEqual('<my-comp>ViewRef</my-comp>');
|
||||
const app = renderComponent(MyApp);
|
||||
// ChangeDetectorRef is the token, ViewRef is historically the constructor
|
||||
expect(toHtml(app)).toEqual('<my-comp>ViewRef</my-comp>');
|
||||
});
|
||||
|
||||
it('should inject attributes', () => {
|
||||
type $MyComp$ = MyComp;
|
||||
type $MyApp$ = MyApp;
|
||||
|
||||
@Component({selector: 'my-comp', template: `{{ title }}`})
|
||||
class MyComp {
|
||||
constructor(@Attribute('title') public title: string|undefined) {}
|
||||
|
||||
// NORMATIVE
|
||||
static ngComponentDef = $r3$.ɵdefineComponent({
|
||||
type: MyComp,
|
||||
tag: 'my-comp',
|
||||
factory: function MyComp_Factory() { return new MyComp($r3$.ɵinjectAttribute('title')); },
|
||||
template: function MyComp_Template(ctx: $MyComp$, cm: $boolean$) {
|
||||
if (cm) {
|
||||
$r3$.ɵT(0);
|
||||
}
|
||||
$r3$.ɵt(0, $r3$.ɵb(ctx.title));
|
||||
}
|
||||
});
|
||||
// /NORMATIVE
|
||||
}
|
||||
|
||||
class MyApp {
|
||||
static ngComponentDef = $r3$.ɵdefineComponent({
|
||||
type: MyApp,
|
||||
tag: 'my-app',
|
||||
factory: function MyApp_Factory() { return new MyApp(); },
|
||||
/** <my-comp></my-comp> */
|
||||
template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) {
|
||||
if (cm) {
|
||||
$r3$.ɵE(0, MyComp, e0_attrs);
|
||||
$r3$.ɵe();
|
||||
}
|
||||
MyComp.ngComponentDef.h(1, 0);
|
||||
$r3$.ɵr(1, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
const e0_attrs = ['title', 'WORKS'];
|
||||
const app = renderComponent(MyApp);
|
||||
// ChangeDetectorRef is the token, ViewRef is historically the constructor
|
||||
expect(toHtml(app)).toEqual('<my-comp title="WORKS">WORKS</my-comp>');
|
||||
});
|
||||
|
||||
// TODO(misko): enable once `providers` and `viewProvdires` are implemented.
|
||||
xit('should inject into an injectable', () => {
|
||||
type $MyApp$ = MyApp;
|
||||
|
||||
@Injectable()
|
||||
class ServiceA {
|
||||
// NORMATIVE
|
||||
static ngInjectableDef = $pending_pr_22458$.defineInjectable({
|
||||
factory: function ServiceA_Factory() { return new ServiceA(); },
|
||||
});
|
||||
// /NORMATIVE
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class ServiceB {
|
||||
// NORMATIVE
|
||||
static ngInjectableDef = $pending_pr_22458$.defineInjectable({
|
||||
factory: function ServiceA_Factory() { return new ServiceB(); },
|
||||
});
|
||||
// /NORMATIVE
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: '',
|
||||
providers: [ServiceA],
|
||||
viewProviders: [ServiceB],
|
||||
})
|
||||
class MyApp {
|
||||
constructor(serviceA: ServiceA, serviceB: ServiceB, injector: Injector) {}
|
||||
|
||||
static ngComponentDef = $r3$.ɵdefineComponent({
|
||||
type: MyApp,
|
||||
tag: 'my-app',
|
||||
factory: function MyApp_Factory() {
|
||||
return new MyApp(
|
||||
$r3$.ɵdirectiveInject(ServiceA), $r3$.ɵdirectiveInject(ServiceB),
|
||||
$pending_pr_22458$.injectInjector());
|
||||
},
|
||||
/** */
|
||||
template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) {},
|
||||
providers: [ServiceA],
|
||||
viewProviders: [ServiceB],
|
||||
});
|
||||
}
|
||||
const e0_attrs = ['title', 'WORKS'];
|
||||
const app = renderComponent(MyApp);
|
||||
// ChangeDetectorRef is the token, ViewRef is historically the constructor
|
||||
expect(toHtml(app)).toEqual('<my-comp title="WORKS">WORKS</my-comp>');
|
||||
});
|
||||
});
|
||||
|
||||
it('should inject attributes', () => {
|
||||
type $MyComp$ = MyComp;
|
||||
type $MyApp$ = MyApp;
|
||||
|
||||
@Component({selector: 'my-comp', template: `{{ title }}`})
|
||||
class MyComp {
|
||||
constructor(@Attribute('title') public title: string|undefined) {}
|
||||
describe('services', () => {
|
||||
// Services should use `inject`
|
||||
@Injectable()
|
||||
class ServiceA {
|
||||
constructor(@Inject(String) name: String, injector: Injector) {}
|
||||
|
||||
// NORMATIVE
|
||||
static ngComponentDef = $r3$.ɵdefineComponent({
|
||||
type: MyComp,
|
||||
tag: 'my-comp',
|
||||
factory: function MyComp_Factory() { return new MyComp($r3$.ɵinjectAttribute('title')); },
|
||||
template: function MyComp_Template(ctx: $MyComp$, cm: $boolean$) {
|
||||
if (cm) {
|
||||
$r3$.ɵT(0);
|
||||
}
|
||||
$r3$.ɵt(0, $r3$.ɵb(ctx.title));
|
||||
}
|
||||
static ngInjectableDef = $pending_pr_22458$.defineInjectable({
|
||||
factory: function ServiceA_Factory() {
|
||||
return new ServiceA(
|
||||
$pending_pr_22458$.inject(String), $pending_pr_22458$.injectInjector());
|
||||
},
|
||||
});
|
||||
// /NORMATIVE
|
||||
}
|
||||
|
||||
class MyApp {
|
||||
static ngComponentDef = $r3$.ɵdefineComponent({
|
||||
type: MyApp,
|
||||
tag: 'my-app',
|
||||
factory: function MyApp_Factory() { return new MyApp(); },
|
||||
/** <my-comp></my-comp> */
|
||||
template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) {
|
||||
if (cm) {
|
||||
$r3$.ɵE(0, MyComp, e0_attrs);
|
||||
$r3$.ɵe();
|
||||
}
|
||||
MyComp.ngComponentDef.h(1, 0);
|
||||
$r3$.ɵr(1, 0);
|
||||
}
|
||||
@Injectable()
|
||||
class ServiceB {
|
||||
constructor(serviceA: ServiceA, @SkipSelf() injector: Injector) {}
|
||||
// NORMATIVE
|
||||
static ngInjectableDef = $pending_pr_22458$.defineInjectable({
|
||||
factory: function ServiceA_Factory() {
|
||||
return new ServiceB(
|
||||
$pending_pr_22458$.inject(ServiceA),
|
||||
$pending_pr_22458$.injectInjector(InjectFlags.SkipSelf));
|
||||
},
|
||||
});
|
||||
// /NORMATIVE
|
||||
}
|
||||
const e0_attrs = ['title', 'WORKS'];
|
||||
const app = renderComponent(MyApp);
|
||||
// ChangeDetectorRef is the token, ViewRef is historically the constructor
|
||||
expect(toHtml(app)).toEqual('<my-comp title="WORKS">WORKS</my-comp>');
|
||||
|
||||
});
|
||||
|
||||
});
|
|
@ -32,7 +32,7 @@ xdescribe('NgModule', () => {
|
|||
constructor(name: String) {}
|
||||
// NORMATIVE
|
||||
static ngInjectableDef = defineInjectable({
|
||||
factory: () => new Toast($r3$.ɵinject(String)),
|
||||
factory: () => new Toast($r3$.ɵdirectiveInject(String)),
|
||||
});
|
||||
// /NORMATIVE
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ xdescribe('NgModule', () => {
|
|||
constructor(toast: Toast) {}
|
||||
// NORMATIVE
|
||||
static ngInjectorDef = defineInjector({
|
||||
factory: () => new MyModule($r3$.ɵinject(Toast)),
|
||||
factory: () => new MyModule($r3$.ɵdirectiveInject(Toast)),
|
||||
provider: [
|
||||
{provide: Toast, deps: [String]}, // If Toast has metadata generate this line
|
||||
Toast, // If Toast has no metadata generate this line.
|
||||
|
@ -69,7 +69,8 @@ xdescribe('NgModule', () => {
|
|||
static ngInjectableDef = defineInjectable({
|
||||
scope: MyModule,
|
||||
factory: () => new BurntToast(
|
||||
$r3$.ɵinject(Toast, $r3$.ɵInjectFlags.Optional), $r3$.ɵinject(String)),
|
||||
$r3$.ɵdirectiveInject(Toast, $r3$.ɵInjectFlags.Optional),
|
||||
$r3$.ɵdirectiveInject(String)),
|
||||
});
|
||||
// /NORMATIVE
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import {Component, ContentChild, Directive, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef} from '../../../src/core';
|
||||
import * as r3 from '../../../src/render3/index';
|
||||
import {pending_pull_22005} from './small_app_spec';
|
||||
import {$pending_pr_22458$} from './pending_api_spec';
|
||||
|
||||
/**
|
||||
* GOALS:
|
||||
|
@ -29,7 +29,7 @@ class ThirdPartyClass {
|
|||
@Injectable()
|
||||
class CompiledWithIvy {
|
||||
// NORMATIVE
|
||||
static ngInjectableDef = pending_pull_22005.defineInjectable(
|
||||
static ngInjectableDef = $pending_pr_22458$.defineInjectable(
|
||||
{factory: function CompileWithIvy_Factory() { return new CompiledWithIvy(); }});
|
||||
// /NORMATIVE
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class CompiledWithIvy {
|
|||
@NgModule({providers: [ThirdPartyClass, CompiledWithIvy]})
|
||||
class CompiledWithIvyModule {
|
||||
// NORMATIVE
|
||||
static ngInjectorDef = pending_pull_22005.defineInjector({
|
||||
static ngInjectorDef = $pending_pr_22458$.defineInjector({
|
||||
providers: [ThirdPartyClass, CompiledWithIvy],
|
||||
factory: function CompiledWithIvyModule_Factory() { return new CompiledWithIvyModule(); }
|
||||
});
|
||||
|
@ -72,7 +72,7 @@ function ngPatch_depsOf_CompiledWithIvyModule() {
|
|||
}
|
||||
function ngPatch_node_modules_some_library_path_public_CompileWithIvy() {
|
||||
/** @__BUILD_OPTIMIZER_COLOCATE__ */
|
||||
(ThirdPartyClass as any).ngInjectableDef = pending_pull_22005.defineInjectable(
|
||||
(ThirdPartyClass as any).ngInjectableDef = $pending_pr_22458$.defineInjectable(
|
||||
{factory: function CompileWithIvy_Factory() { return new ThirdPartyClass(); }});
|
||||
}
|
||||
// /NORMATIVE
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {InjectFlags, InjectionToken, Injector, Type} from '@angular/core';
|
||||
|
||||
|
||||
|
||||
// TODO: remove once https://github.com/angular/angular/pull/22458 lands
|
||||
export class $pending_pr_22458$ {
|
||||
static defineInjectable<T>({providerFor, factory}: {providerFor?: Type<any>, factory: () => T}):
|
||||
{providerFor: Type<any>| null, factory: () => T} {
|
||||
return {providerFor: providerFor || null, factory: factory};
|
||||
}
|
||||
|
||||
static defineInjector<T>({factory, providers}: {factory: () => T, providers: any[]}):
|
||||
{factory: () => T, providers: any[]} {
|
||||
return {factory: factory, providers: providers};
|
||||
}
|
||||
|
||||
static injectInjector(flags?: InjectFlags): Injector { return null !; }
|
||||
|
||||
static inject<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags): T { return null as any; }
|
||||
}
|
|
@ -11,24 +11,11 @@ import {Component, ContentChild, Directive, EventEmitter, Injectable, Input, NgM
|
|||
import {withBody} from '@angular/core/testing';
|
||||
|
||||
import * as r3 from '../../../src/render3/index';
|
||||
import {$pending_pr_22458$} from './pending_api_spec';
|
||||
|
||||
/// See: `normative.md`
|
||||
|
||||
|
||||
// TODO: remove once https://github.com/angular/angular/pull/22005 lands
|
||||
export class pending_pull_22005 {
|
||||
static defineInjectable<T>({scope, factory}: {scope?: Type<any>, factory: () => T}):
|
||||
{scope: Type<any>| null, factory: () => T} {
|
||||
return {scope: scope || null, factory: factory};
|
||||
}
|
||||
|
||||
static defineInjector<T>({factory, providers}: {factory: () => T, providers: any[]}):
|
||||
{factory: () => T, providers: any[]} {
|
||||
return {factory: factory, providers: providers};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
interface ToDo {
|
||||
text: string;
|
||||
|
@ -46,7 +33,7 @@ class AppState {
|
|||
];
|
||||
|
||||
// NORMATIVE
|
||||
static ngInjectableDef = pending_pull_22005.defineInjectable({factory: () => new AppState()});
|
||||
static ngInjectableDef = $pending_pr_22458$.defineInjectable({factory: () => new AppState()});
|
||||
// /NORMATIVE
|
||||
}
|
||||
|
||||
|
@ -74,7 +61,7 @@ class ToDoAppComponent {
|
|||
type: ToDoAppComponent,
|
||||
tag: 'todo-app',
|
||||
factory: function ToDoAppComponent_Factory() {
|
||||
return new ToDoAppComponent(r3.inject(AppState));
|
||||
return new ToDoAppComponent(r3.directiveInject(AppState));
|
||||
},
|
||||
template: function ToDoAppComponent_Template(ctx: ToDoAppComponent, cm: boolean) {
|
||||
if (cm) {
|
||||
|
@ -171,7 +158,7 @@ const e1_attrs = ['type', 'checkbox'];
|
|||
})
|
||||
class ToDoAppModule {
|
||||
// NORMATIVE
|
||||
static ngInjectorDef = pending_pull_22005.defineInjector({
|
||||
static ngInjectorDef = $pending_pr_22458$.defineInjector({
|
||||
factory: () => new ToDoAppModule(),
|
||||
providers: [AppState],
|
||||
});
|
||||
|
|
|
@ -32,7 +32,6 @@ describe('component', () => {
|
|||
},
|
||||
factory: () => new CounterComponent,
|
||||
inputs: {count: 'count'},
|
||||
methods: {increment: 'increment'}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import {ChangeDetectorRef, ElementRef, TemplateRef, ViewContainerRef} from '@ang
|
|||
|
||||
import {defineComponent} from '../../src/render3/definition';
|
||||
import {InjectFlags, bloomAdd, bloomFindPossibleInjector, getOrCreateNodeInjector, injectAttribute} from '../../src/render3/di';
|
||||
import {NgOnChangesFeature, PublicFeature, defineDirective, inject, injectChangeDetectorRef, injectElementRef, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
||||
import {NgOnChangesFeature, PublicFeature, defineDirective, directiveInject, injectChangeDetectorRef, injectElementRef, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
||||
import {bind, container, containerRefreshEnd, containerRefreshStart, createLNode, createLView, createTView, directiveRefresh, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, enterView, interpolation2, leaveView, load, projection, projectionDef, text, textBinding} from '../../src/render3/instructions';
|
||||
import {LInjector} from '../../src/render3/interfaces/injector';
|
||||
import {LNodeFlags} from '../../src/render3/interfaces/node';
|
||||
|
@ -59,7 +59,7 @@ describe('di', () => {
|
|||
constructor(a: DirectiveA, b: DirectiveB) { this.value = a.value + b.value; }
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: DirectiveC,
|
||||
factory: () => new DirectiveC(inject(DirectiveA), inject(DirectiveB))
|
||||
factory: () => new DirectiveC(directiveInject(DirectiveA), directiveInject(DirectiveB))
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ describe('di', () => {
|
|||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: DirectiveSameInstance,
|
||||
factory: () => new DirectiveSameInstance(injectElementRef(), inject(Directive))
|
||||
factory: () => new DirectiveSameInstance(injectElementRef(), directiveInject(Directive))
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ describe('di', () => {
|
|||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: DirectiveSameInstance,
|
||||
factory: () => new DirectiveSameInstance(injectTemplateRef(), inject(Directive))
|
||||
factory: () => new DirectiveSameInstance(injectTemplateRef(), directiveInject(Directive))
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,8 @@ describe('di', () => {
|
|||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: DirectiveSameInstance,
|
||||
factory: () => new DirectiveSameInstance(injectViewContainerRef(), inject(Directive))
|
||||
factory:
|
||||
() => new DirectiveSameInstance(injectViewContainerRef(), directiveInject(Directive))
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -540,7 +541,8 @@ describe('di', () => {
|
|||
static ngComponentDef = defineComponent({
|
||||
type: MyApp,
|
||||
tag: 'my-app',
|
||||
factory: () => new MyApp(inject(String as any, InjectFlags.Default, 'DefaultValue')),
|
||||
factory: () => new MyApp(
|
||||
directiveInject(String as any, InjectFlags.Default, 'DefaultValue')),
|
||||
template: () => null
|
||||
});
|
||||
}
|
||||
|
@ -565,7 +567,7 @@ describe('di', () => {
|
|||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: ChildDirective,
|
||||
factory: () => new ChildDirective(inject(ParentDirective)),
|
||||
factory: () => new ChildDirective(directiveInject(ParentDirective)),
|
||||
features: [PublicFeature]
|
||||
});
|
||||
}
|
||||
|
@ -577,7 +579,8 @@ describe('di', () => {
|
|||
}
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: Child2Directive,
|
||||
factory: () => new Child2Directive(inject(ParentDirective), inject(ChildDirective))
|
||||
factory: () => new Child2Directive(
|
||||
directiveInject(ParentDirective), directiveInject(ChildDirective))
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue