Learn the concepts of TView and LView in Angular through one-step debugging

Problem description

Code locations covered in this article: https://github.com/wangzixi-d...

Look at a group of parent components and child components:

@Component({
    selector: 'child',
    template: `<span>I am a child.</span>`
  })
  export class ChildViewComponent {}

  @Component({
    selector: 'parent',
    template: `
      <div>
        projected content: 
        <ng-content></ng-content>
      </div>
    `
  })
  export class ParentComponent {}

  @Component({
    selector: 'demo',
    template: `
      <parent id="p1">
      <child id="c1"></child>
      </parent>
      <child id="c2"></child>
    `
  })
  export class Demo {}

The parent Component defines a content projection area, and the contents of the child Component are projected through the following highlight Code:

That is, the area:

Final runtime effect:

problem analysis

When the above application is load ed but the bootstrap has not been completed, Ivy Resolve it to the following TView:

const tChildComponentView = new TView(
  tData: [
    new TElementNode('span'),
    new TTextNode('I am a child.'),
  ],
  ...,
);
const tParentComponentView = new TView(
  tData: [
    new TElementNode('div'),
    new TTextNode('projected content: '),
    new TProjectionNode(),
  ],
  ...,
);
const tDemoAppView = new TView(
  tData: [
    new TElementNode('parent', ['id', 'p1']),
    new TElementNode('child', ['id', 'c1']),
    new TElementNode('child', ['id', 'c2']),
  ],
  ...,
)

The next step is bootstrap. The specific logic is to create LView based on TView:

const lParentComponentView_p1 = new LView(
  tParentComponentView,
  new ParentComponent(...),
  document.createElement('div'),
  document.createText('projected content: '),
);
const lChildComponentView_c1 = new LView(
  tChildComponentView,
  new ChildComponent(...),
  document.createElement('span'),
  document.createText('I am a child.'),
);
const lChildComponentView_c2 = new LView(
  tChildComponentView,
  new ChildComponent(...),
  document.createElement('span'),
  document.createText('I am a child.'),
);
const lDemoAppView = new LView(
  tDemoAppView,
  new DemoApp(...),
  document.createElement('parent'),
  lParentComponentView_p1,
  document.createElement('child'),
  lChildComponentView_c1,
  document.createElement('child'),
  lChildComponentView_c2,
)

The above logic in the debugger is shown in the following figure:

Jerry appcomponent is maintained as bootstrap Component:

The above code shows the difference between TView and LView.

Look at ChildComponent. There is only one instance of TView, but there are two instances of LView, because ChildComponent is used twice. Another key difference is that LView stores only data specific to the component instance -- for example, the component instance and the associated DOM node. TView stores information shared between all instances of a component -- for example, which DOM nodes need to be created.

In the above example, LView is displayed as a class (new LView(...). In fact, we store it as an array ([...]). Lviews are stored as an array for memory performance reasons. Each template has a different number of DOM nodes and subcomponents / instructions, and storing them in an array is the most effective way.

The meaning of using an array for storage is that it is not clear where the instance data is stored in the array. TData is used to describe the content stored in each location in LView. So LView itself is not sufficient for reasoning because it stores values without context. TView describes what the component needs, but it does not store instance information. By putting LView and TView together, Ivy can access and reason about the values in LView. LView stores values, while TView stores the meaning of LView values, similar to the concept of metadata or schema.

For simplicity, LView stores only DOM nodes. In practice, LView also stores bindings, injectors, purifiers, and anything else related to the view state (with corresponding entries in TView/TData)

summary

One way to think about View and View is to associate these concepts with object-oriented programming. TView is like a class, and View is like a class instance.

Keywords: Javascript Front-end angular html5 html

Added by ozfred on Sat, 05 Mar 2022 06:12:15 +0200