feat(ivy): expose node injector as part of debug context (#26210)

PR Close #26210
This commit is contained in:
Pawel Kozlowski 2018-10-02 14:42:34 +02:00 committed by Jason Aden
parent 35bf95281f
commit fdaf573073
5 changed files with 46 additions and 44 deletions

View File

@ -9,9 +9,9 @@ import {Injector} from '../di/injector';
import {assertDefined} from './assert';
import {LContext, discoverDirectiveIndices, discoverDirectives, discoverLocalRefs, getContext, isComponentInstance, readPatchedLViewData} from './context_discovery';
import {LElementNode, TNode, TNodeFlags} from './interfaces/node';
import {CONTEXT, FLAGS, INJECTOR, LViewData, LViewFlags, PARENT, RootContext, TVIEW} from './interfaces/view';
import {NodeInjector} from './di';
import {LElementNode, TElementNode, TNode, TNodeFlags} from './interfaces/node';
import {CONTEXT, FLAGS, LViewData, LViewFlags, PARENT, RootContext, TVIEW} from './interfaces/view';
/**
* NOTE: The following functions might not be ideal for core usage in Angular...
@ -89,9 +89,11 @@ export function getRootComponents(target: {}): any[] {
* Returns the injector instance that is associated with
* the element, component or directive.
*/
export function getInjector(target: {}): Injector|null {
const context = loadContext(target) !;
return context.lViewData[INJECTOR] || null;
export function getInjector(target: {}): Injector {
const context = loadContext(target);
const tNode = context.lViewData[TVIEW].data[context.lNodeIndex] as TElementNode;
return new NodeInjector(tNode, context.lViewData);
}
/**

View File

@ -14,7 +14,6 @@ import {StyleSanitizeFn} from '../sanitization/style_sanitizer';
import {assertDefined, assertEqual, assertLessThan, assertNotEqual} from './assert';
import {attachPatchData, getLElementFromComponent, readElementValue, readPatchedLViewData} from './context_discovery';
import {getRootView} from './discovery_utils';
import {throwCyclicDependencyError, throwErrorIfNoChangesMode, throwMultipleComponentError} from './errors';
import {executeHooks, executeInitHooks, queueInitHooks, queueLifecycleHooks} from './hooks';
import {ACTIVE_INDEX, LContainer, RENDER_PARENT, VIEWS} from './interfaces/container';
@ -29,7 +28,7 @@ import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert';
import {appendChild, appendProjectedNode, createTextNode, findComponentView, getHostElementNode, getLViewChild, getRenderParent, insertView, removeView} from './node_manipulation';
import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher';
import {allocStylingContext, createStylingContextTemplate, renderStyling as renderElementStyles, updateClassProp as updateElementClassProp, updateStyleProp as updateElementStyleProp, updateStylingMap} from './styling/class_and_style_bindings';
import {assertDataInRangeInternal, getLNode, isContentQueryHost, isDifferent, loadElementInternal, loadInternal, stringify} from './util';
import {assertDataInRangeInternal, getLNode, getRootView, isContentQueryHost, isDifferent, loadElementInternal, loadInternal, stringify} from './util';
/**

View File

@ -11,7 +11,7 @@ import {devModeEqual} from '../change_detection/change_detection_util';
import {assertDefined, assertLessThan} from './assert';
import {readElementValue, readPatchedLViewData} from './context_discovery';
import {LContainerNode, LElementContainerNode, LElementNode, TNode, TNodeFlags} from './interfaces/node';
import {CONTEXT, FLAGS, HEADER_OFFSET, LViewData, LViewFlags, PARENT, RootContext, TData} from './interfaces/view';
import {CONTEXT, FLAGS, HEADER_OFFSET, LViewData, LViewFlags, PARENT, RootContext, TData, TVIEW} from './interfaces/view';

View File

@ -666,10 +666,10 @@
"name": "getRendererFactory"
},
{
"name": "getRootContext$1"
"name": "getRootContext"
},
{
"name": "getRootView$1"
"name": "getRootView"
},
{
"name": "getStyleSanitizer"

View File

@ -7,7 +7,7 @@
*/
import {StaticInjector} from '../../src/di/injector';
import {getComponent, getDirectives, getHostComponent, getInjector, getLocalRefs, getRootComponents} from '../../src/render3/discovery_utils';
import {RenderFlags, defineComponent, defineDirective} from '../../src/render3/index';
import {PublicFeature, RenderFlags, defineComponent, defineDirective} from '../../src/render3/index';
import {element, elementEnd, elementStart, elementStyling, elementStylingApply} from '../../src/render3/instructions';
import {ComponentFixture} from './render_util';
@ -220,50 +220,51 @@ describe('discovery utils', () => {
});
});
describe('getInjector()', () => {
it('should return the instance of the injector that was passed into the component', () => {
describe('getInjector', () => {
it('should return an injector that can return directive instances', () => {
class Comp {
static ngComponentDef = defineComponent({
type: Comp,
selectors: [['comp']],
factory: () => new Comp(),
consts: 1,
consts: 0,
vars: 0,
template: (rf: RenderFlags, ctx: Comp) => {
if (rf & RenderFlags.Create) {
element(0, 'div');
}
}
});
}
const injector = new StaticInjector([]);
const fixture = new ComponentFixture(Comp, {injector});
fixture.update();
expect(getInjector(fixture.hostElement) !).toBe(injector);
});
it('should return null when there is no injector passed into a component', () => {
class Comp {
static ngComponentDef = defineComponent({
type: Comp,
selectors: [['comp']],
factory: () => new Comp(),
consts: 1,
vars: 0,
template: (rf: RenderFlags, ctx: Comp) => {
if (rf & RenderFlags.Create) {
element(0, 'div');
}
}
template: (rf: RenderFlags, ctx: Comp) => {},
features: [PublicFeature]
});
}
const fixture = new ComponentFixture(Comp);
fixture.update();
expect(getInjector(fixture.hostElement)).toEqual(null);
const nodeInjector = getInjector(fixture.hostElement);
expect(nodeInjector.get(Comp)).toEqual(jasmine.any(Comp));
});
it('should return an injector that falls-back to a module injector', () => {
class Comp {
static ngComponentDef = defineComponent({
type: Comp,
selectors: [['comp']],
factory: () => new Comp(),
consts: 0,
vars: 0,
template: (rf: RenderFlags, ctx: Comp) => {},
features: [PublicFeature]
});
}
class TestToken {}
const staticInjector = new StaticInjector([{provide: TestToken, useValue: new TestToken()}]);
const fixture = new ComponentFixture(Comp, {injector: staticInjector});
fixture.update();
const nodeInjector = getInjector(fixture.hostElement);
expect(nodeInjector.get(TestToken)).toEqual(jasmine.any(TestToken));
});
});