且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Angular应用bootstrap时的version检测机制

更新时间:2022-09-13 12:37:07

core.js里: create(injector, projectableNodes, rootSelectorOrNode, ngModule) {

       ngModule = ngModule || this.ngModule;

       /** @type {?} */

       const rootViewInjector = ngModule ? createChainedInjector(injector, ngModule.injector) : injector;

       /** @type {?} */

       const rendererFactory = (/** @type {?} */ (rootViewInjector.get(RendererFactory2, domRendererFactory3)));

       /** @type {?} */

       const sanitizer = rootViewInjector.get(Sanitizer, null);

       /** @type {?} */

       const hostRenderer = rendererFactory.createRenderer(null, this.componentDef);

       // Determine a tag name used for creating host elements when this component is created

       // dynamically. Default to 'div' if this component did not specify any tag name in its selector.

       /** @type {?} */

       const elementName = (/** @type {?} */ (this.componentDef.selectors[0][0])) || 'div';

       /** @type {?} */

       const hostRNode = rootSelectorOrNode ?

           locateHostElement(hostRenderer, rootSelectorOrNode, this.componentDef.encapsulation) :

           elementCreate(elementName, rendererFactory.createRenderer(null, this.componentDef), getNamespace$1(elementName));

       /** @type {?} */

       const rootFlags = this.componentDef.onPush ? 64 /* Dirty */ | 512 /* IsRoot */ :

           16 /* CheckAlways */ | 512 /* IsRoot */;

       // Check whether this Component needs to be isolated from other components, i.e. whether it

       // should be placed into its own (empty) root context or existing root context should be used.

       // Note: this is internal-only convention and might change in the future, so it should not be

       // relied upon externally.

       /** @type {?} */

       const isIsolated = typeof rootSelectorOrNode === 'string' &&

           /^#root-ng-internal-isolated-\d+/.test(rootSelectorOrNode);

       /** @type {?} */

       const rootContext = createRootContext();

       // Create the root view. Uses empty TView and ContentTemplate.

       /** @type {?} */

       const rootTView = createTView(0 /* Root */, -1, null, 1, 0, null, null, null, null, null);

       /** @type {?} */

       const rootLView = createLView(null, rootTView, rootContext, rootFlags, null, null, rendererFactory, hostRenderer, sanitizer, rootViewInjector);

       // rootView is the parent when bootstrapping

       // TODO(misko): it looks like we are entering view here but we don't really need to as

       // `renderView` does that. However as the code is written it is needed because

       // `createRootComponentView` and `createRootComponent` both read global state. Fixing those

       // issues would allow us to drop this.

       enterView(rootLView, null);

       /** @type {?} */

       let component;

       /** @type {?} */

       let tElementNode;

       try {

           /** @type {?} */

           const componentView = createRootComponentView(hostRNode, this.componentDef, rootLView, rendererFactory, hostRenderer);

           if (hostRNode) {

               if (rootSelectorOrNode) {

                   setUpAttributes(hostRenderer, hostRNode, ['ng-version', VERSION.full]);

               }

               else {

                   // If host element is created as a part of this function call (i.e. `rootSelectorOrNode`

                   // is not defined), also apply attributes and classes extracted from component selector.

                   // Extract attributes and classes from the first selector only to match VE behavior.

                   const { attrs, classes } = extractAttrsAndClassesFromSelector(this.componentDef.selectors[0]);

                   if (attrs) {

                       setUpAttributes(hostRenderer, hostRNode, attrs);

                   }

                   if (classes && classes.length > 0) {

                       writeDirectClass(hostRenderer, hostRNode, classes.join(' '));

                   }

               }

           }

           tElementNode = (/** @type {?} */ (getTNode(rootTView, 0)));

           if (projectableNodes !== undefined) {

               /** @type {?} */

               const projection = tElementNode.projection = [];

               for (let i = 0; i < this.ngContentSelectors.length; i++) {

                   /** @type {?} */

                   const nodesforSlot = projectableNodes[i];

                   // Projectable nodes can be passed as array of arrays or an array of iterables (ngUpgrade

                   // case). Here we do normalize passed data structure to be an array of arrays to avoid

                   // complex checks down the line.

                   // We also normalize the length of the passed in projectable nodes (to match the number of

                   // slots defined by a component).

                   projection.push(nodesforSlot != null ? Array.from(nodesforSlot) : null);

               }

           }

           // TODO: should LifecycleHooksFeature and other host features be generated by the compiler and

           // executed here?

           // Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref

           component = createRootComponent(componentView, this.componentDef, rootLView, rootContext, [LifecycleHooksFeature]);

           renderView(rootTView, rootLView, null);

       }

       finally {

           leaveView();

       }

       /** @type {?} */

       const componentRef = new ComponentRef$1(this.componentType, component, createElementRef(ElementRef, tElementNode, rootLView), rootLView, tElementNode);

       if (!rootSelectorOrNode || isIsolated) {

           // The host element of the internal or isolated root view is attached to the component's host

           // view node.

           ngDevMode && assertNodeOfPossibleTypes(rootTView.node, 2 /* View */);

           (/** @type {?} */ (rootTView.node)).child = tElementNode;

       }

       return componentRef;

   }

}Angular应用bootstrap时的version检测机制