parent
69d359bb51
commit
51ca643c27
|
@ -18,6 +18,7 @@ export {
|
|||
injectTemplateRef as ɵinjectTemplateRef,
|
||||
injectViewContainerRef as ɵinjectViewContainerRef,
|
||||
injectChangeDetectorRef as ɵinjectChangeDetectorRef,
|
||||
injectAttribute as ɵinjectAttribute,
|
||||
InjectFlags as ɵInjectFlags,
|
||||
PublicFeature as ɵPublicFeature,
|
||||
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 {Type} from '../type';
|
||||
|
||||
import {assertLessThan} from './assert';
|
||||
import {assertLessThan, assertNotNull} from './assert';
|
||||
import {assertPreviousIsParent, getDirectiveInstance, getPreviousOrParentNode, getRenderer, renderEmbeddedTemplate} from './instructions';
|
||||
import {ComponentTemplate, DirectiveDef} from './interfaces/definition';
|
||||
import {LInjector} from './interfaces/injector';
|
||||
|
@ -234,6 +234,54 @@ export function injectChangeDetectorRef(): viewEngine_ChangeDetectorRef {
|
|||
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).
|
||||
* Or, if it already exists, retrieves the existing instance.
|
||||
|
|
|
@ -11,10 +11,11 @@ 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, 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';
|
||||
|
||||
|
||||
|
||||
// Naming scheme:
|
||||
// - Capital letters are for creating things: T(Text), E(Element), D(Directive), V(View),
|
||||
// C(Container), L(Listener)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* 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 {renderComponent, toHtml} from '../render_util';
|
||||
|
||||
|
@ -60,4 +60,49 @@ describe('injection', () => {
|
|||
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 {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 {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';
|
||||
|
@ -465,6 +465,29 @@ describe('di', () => {
|
|||
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', () => {
|
||||
|
|
Loading…
Reference in New Issue