parent
69d359bb51
commit
51ca643c27
|
@ -18,6 +18,7 @@ export {
|
||||||
injectTemplateRef as ɵinjectTemplateRef,
|
injectTemplateRef as ɵinjectTemplateRef,
|
||||||
injectViewContainerRef as ɵinjectViewContainerRef,
|
injectViewContainerRef as ɵinjectViewContainerRef,
|
||||||
injectChangeDetectorRef as ɵinjectChangeDetectorRef,
|
injectChangeDetectorRef as ɵinjectChangeDetectorRef,
|
||||||
|
injectAttribute as ɵinjectAttribute,
|
||||||
InjectFlags as ɵInjectFlags,
|
InjectFlags as ɵInjectFlags,
|
||||||
PublicFeature as ɵPublicFeature,
|
PublicFeature as ɵPublicFeature,
|
||||||
NgOnChangesFeature as ɵNgOnChangesFeature,
|
NgOnChangesFeature as ɵNgOnChangesFeature,
|
||||||
|
|
|
@ -18,7 +18,7 @@ import {ViewContainerRef as viewEngine_ViewContainerRef} from '../linker/view_co
|
||||||
import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, ViewRef as viewEngine_ViewRef} from '../linker/view_ref';
|
import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, ViewRef as viewEngine_ViewRef} from '../linker/view_ref';
|
||||||
import {Type} from '../type';
|
import {Type} from '../type';
|
||||||
|
|
||||||
import {assertLessThan} from './assert';
|
import {assertLessThan, assertNotNull} from './assert';
|
||||||
import {assertPreviousIsParent, getDirectiveInstance, getPreviousOrParentNode, getRenderer, renderEmbeddedTemplate} from './instructions';
|
import {assertPreviousIsParent, getDirectiveInstance, getPreviousOrParentNode, getRenderer, renderEmbeddedTemplate} from './instructions';
|
||||||
import {ComponentTemplate, DirectiveDef} from './interfaces/definition';
|
import {ComponentTemplate, DirectiveDef} from './interfaces/definition';
|
||||||
import {LInjector} from './interfaces/injector';
|
import {LInjector} from './interfaces/injector';
|
||||||
|
@ -234,6 +234,54 @@ export function injectChangeDetectorRef(): viewEngine_ChangeDetectorRef {
|
||||||
return getOrCreateChangeDetectorRef(getOrCreateNodeInjector(), null);
|
return getOrCreateChangeDetectorRef(getOrCreateNodeInjector(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject static attribute value into directive constructor.
|
||||||
|
*
|
||||||
|
* This method is used with `factory` functions which are generated as part of
|
||||||
|
* `defineDirective` or `defineComponent`. The method retrieves the static value
|
||||||
|
* of an attribute. (Dynamic attributes are not supported since they are not resolved
|
||||||
|
* at the time of injection and can change over time.)
|
||||||
|
*
|
||||||
|
* # Example
|
||||||
|
* Given:
|
||||||
|
* ```
|
||||||
|
* @Component(...)
|
||||||
|
* class MyComponent {
|
||||||
|
* constructor(@Attribute('title') title: string) { ... }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
* When instantiated with
|
||||||
|
* ```
|
||||||
|
* <my-component title="Hello"></my-component>
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Then factory method generated is:
|
||||||
|
* ```
|
||||||
|
* MyComponent.ngComponentDef = defineComponent({
|
||||||
|
* factory: () => new MyComponent(injectAttribute('title'))
|
||||||
|
* ...
|
||||||
|
* })
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @experimental
|
||||||
|
*/
|
||||||
|
export function injectAttribute(attrName: string): string|undefined {
|
||||||
|
ngDevMode && assertPreviousIsParent();
|
||||||
|
const lElement = getPreviousOrParentNode() as LElementNode;
|
||||||
|
ngDevMode && assertNodeType(lElement, LNodeFlags.Element);
|
||||||
|
const tElement = lElement.tNode !;
|
||||||
|
ngDevMode && assertNotNull(tElement, 'expecting tNode');
|
||||||
|
const attrs = tElement.attrs;
|
||||||
|
if (attrs) {
|
||||||
|
for (let i = 0; i < attrs.length; i = i + 2) {
|
||||||
|
if (attrs[i] == attrName) {
|
||||||
|
return attrs[i + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a ViewRef and stores it on the injector as ChangeDetectorRef (public alias).
|
* Creates a ViewRef and stores it on the injector as ChangeDetectorRef (public alias).
|
||||||
* Or, if it already exists, retrieves the existing instance.
|
* Or, if it already exists, retrieves the existing instance.
|
||||||
|
|
|
@ -11,10 +11,11 @@ import {NgOnChangesFeature, PublicFeature, defineComponent, defineDirective, def
|
||||||
import {InjectFlags} from './di';
|
import {InjectFlags} from './di';
|
||||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveType} from './interfaces/definition';
|
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, injectChangeDetectorRef, injectElementRef, injectTemplateRef, injectViewContainerRef} from './di';
|
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 {CssSelector} from './interfaces/projection';
|
export {CssSelector} from './interfaces/projection';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Naming scheme:
|
// Naming scheme:
|
||||||
// - Capital letters are for creating things: T(Text), E(Element), D(Directive), V(View),
|
// - Capital letters are for creating things: T(Text), E(Element), D(Directive), V(View),
|
||||||
// C(Container), L(Listener)
|
// C(Container), L(Listener)
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {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, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core';
|
||||||
import * as $r3$ from '../../../src/core_render3_private_export';
|
import * as $r3$ from '../../../src/core_render3_private_export';
|
||||||
import {renderComponent, toHtml} from '../render_util';
|
import {renderComponent, toHtml} from '../render_util';
|
||||||
|
|
||||||
|
@ -60,4 +60,49 @@ describe('injection', () => {
|
||||||
expect(toHtml(app)).toEqual('<my-comp>ViewRef</my-comp>');
|
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>');
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
|
@ -9,7 +9,7 @@
|
||||||
import {ChangeDetectorRef, ElementRef, TemplateRef, ViewContainerRef} from '@angular/core';
|
import {ChangeDetectorRef, ElementRef, TemplateRef, ViewContainerRef} from '@angular/core';
|
||||||
|
|
||||||
import {defineComponent} from '../../src/render3/definition';
|
import {defineComponent} from '../../src/render3/definition';
|
||||||
import {InjectFlags, bloomAdd, bloomFindPossibleInjector, getOrCreateNodeInjector} from '../../src/render3/di';
|
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, inject, 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 {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 {LInjector} from '../../src/render3/interfaces/injector';
|
||||||
|
@ -465,6 +465,29 @@ describe('di', () => {
|
||||||
expect(dir !.cdr).toBe(dirSameInstance !.cdr);
|
expect(dir !.cdr).toBe(dirSameInstance !.cdr);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should injectAttribute', () => {
|
||||||
|
let exist: string|undefined = 'wrong';
|
||||||
|
let nonExist: string|undefined = 'wrong';
|
||||||
|
class MyApp {
|
||||||
|
static ngComponentDef = defineComponent({
|
||||||
|
type: MyApp,
|
||||||
|
tag: 'my-app',
|
||||||
|
factory: () => new MyApp(),
|
||||||
|
template: function(ctx: MyApp, cm: boolean) {
|
||||||
|
if (cm) {
|
||||||
|
elementStart(0, 'div', ['exist', 'existValue', 'other', 'ignore']);
|
||||||
|
exist = injectAttribute('exist');
|
||||||
|
nonExist = injectAttribute('nonExist');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const app = renderComponent(MyApp);
|
||||||
|
expect(exist).toEqual('existValue');
|
||||||
|
expect(nonExist).toEqual(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('inject', () => {
|
describe('inject', () => {
|
||||||
|
|
Loading…
Reference in New Issue