Web Component

Before introducing Angular Components, let’s take a quick look at W3C Web Components

define

  • W3C proposed a standard for Web Component to unify the componentization standard approach.
  • Each component contains its own HTML, CSS, and JS code.
  • The Web Component standard includes four important concepts:
  1. Custom Elements: You can create Custom HTML tags and Elements;
  2. HTML Templates: Use<template>The tag pre-defines something, but instead of loading it into the page, it initializes it with JS code.
  3. Shadow DOM (virtual DOM) : You can create DOM subtrees that are completely independent of other elements.
  4. HTML Imports: A method of introducing other HTML documents into an HTML document,<link rel="import" href="example.html" />.

In a word, the ability to create custom tags to introduce components is the basis for componentization of the front end, reference HTML files and HTML templates in the page is used to support writing component views and component resource management, and Shadow DOM is used to isolate conflicts and impacts of code between components.

The sample

Define the hello – component

<template id="hello-template">
    <style>
        h1 {
            color: red;
        }
    </style>
    <h1>Hello Web Component!</h1>
</template>

<script>

    // Points to the imported document, in this case index.html
    var indexDoc = document;

    // Points to the imported document, the current document hello.html
    var helloDoc = (indexDoc._currentScript || indexDoc.currentScript).ownerDocument;

    // Get the template above
    var tmpl = helloDoc.querySelector('#hello-template');

    // Create a new element prototype that inherits from HTMLElement
    var HelloProto = Object.create(HTMLElement.prototype);

    // Set Shadow DOM and clone the template into it
    HelloProto.createdCallback = function() {
        var root = this.createShadowRoot();
        root.appendChild(indexDoc.importNode(tmpl.content, true));
    };

    // Register a new element
    var hello = indexDoc.registerElement('hello-component', {
        prototype: HelloProto
    });
</script>
Copy the code

Use the hello – component


      
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-COMPATIBLE" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="author" content="Lai Xiang combustion, [email protected], http://www.laixiangran.cn"/>
    <title>Web Component</title>
    <! Import custom components -->
    <link rel="import" href="hello.html">
</head>
<body>
    <! -- Custom tags -->
    <hello-component></hello-component>
</body>
</html>
Copy the code

As you can see from the above code, hello.html is a standard defined component (named Hello-component) that has its own structure, style, and logic. You can then import the component file into index.html and use it as a normal tag.

Angular Component

Angular Component is a type of directive that can be understood as having a template. The other two are attribute and structural directives.

The basic composition of

@Component({
    selector: 'demo-component',
    template: 'Demo Component'
})
export class DemoComponent {}
Copy the code
  • Component decorator: must be used by each component class@componentDecorates to become an Angular component.
  • Component metadata:selector,templateThe following sections will focus on the meaning of each metadata.
  • Component classes: A component is actually a normal class in which the logic of the component is defined and implemented.
  • Component templates: Each component is associated with a template that will eventually be rendered to the page, this one on the pageDOMThe element is the host element for this component instance.

Component metadata

Own metadata attributes

The name of the type role
animations AnimationEntryMetadata[] Sets the animation of the component
changeDetection ChangeDetectionStrategy Sets the change monitoring policy for the component
encapsulation ViewEncapsulation Sets the view wrapping options for the component
entryComponents any[] The Settings will be dynamically inserted into the list of components in the component view
interpolation [string, string] Interpolation tag for a custom component. Default is double curly braces{{}}
moduleId string Sets the module ID of this component under the ES/CommonJS specification, which is used to resolve the relative path to the template style
styleUrls string[] Sets the external style file referenced by the component
styles string[] Sets the inline style used by the component
template string Sets the inline template for the component
templateUrl string Set the path where the component template resides
viewProviders Provider[] Sets the services available to the component and all its children (excluding ContentChildren)

From the core/Directive to inherit

The name of the type role
exportAs string Aliases the component instance in the template so that it can be invoked in the template
host {[key: string]: string} Sets the component’s events, actions, properties, and so on
inputs string[] Sets the input properties of the component
outputs string[] Sets the output properties of the component
providers Provider[] Sets the services (dependency injection) available to the component and all its children, including ContentChildren
queries {[key: string]: any} Sets the query that needs to be injected into the component
selector string Set the CSS selector used to identify the component in the template (the component’s custom tag)

Several metadata details

The equivalent syntax of the following metadata is more concise than metadata Settings. Therefore, the equivalent syntax is recommended.

inputs

@Component({
    selector: 'demo-component',
    inputs: ['param']})export class DemoComponent {
    param: any;
}
Copy the code

Is equivalent to:

@Component({
    selector: 'demo-component'
})
export class DemoComponent {
    @Input() param: any;
}
Copy the code

outputs

@Component({
    selector: 'demo-component',
    outputs: ['ready']})export class DemoComponent {
    ready = new eventEmitter<false> (); }Copy the code

Is equivalent to:

@Component({
    selector: 'demo-component'
})
export class DemoComponent {
    @Output() ready = new eventEmitter<false> (); }Copy the code

host

@Component({
    selector: 'demo-component',
    host: {
        '(click)': 'onClick($event.target)'./ / event
        'role': 'nav'./ / property
        '[class.pressed]': 'isPressed'./ / class}})export class DemoComponent {
    isPressed: boolean = true;

    onClick(elem: HTMLElement) {
        console.log(elem); }}Copy the code

Is equivalent to:

@Component({
    selector: 'demo-component'
})
export class DemoComponent {
    @HostBinding('attr.role') role = 'nav';
    @HostBinding('class.pressed') isPressed: boolean = true;

    @HostListener('click'['$event.target'])
    onClick(elem: HTMLElement) {
        console.log(elem); }}Copy the code

Queries – View queries

@Component({
    selector: 'demo-component',
    template: `  
      
Demo Component
`
, queries: { theInput: new ViewChild('theInput')}})export class DemoComponent { theInput: ElementRef; } Copy the code

Is equivalent to:

@Component({
    selector: 'demo-component',
    template: `  
      
Demo Component
`
}) export class DemoComponent { @ViewChild('theInput') theInput: ElementRef; } Copy the code

Queries – Content query

<my-list>
    <li *ngFor="let item of items;">{{item}}</li>
</my-list>
Copy the code
@Directive({
    selector: 'li'
})
export class ListItem {}
Copy the code
@Component({
    selector: 'my-list',
    template: ` 
      
`
, queries: { items: new ContentChild(ListItem) } }) export class MyListComponent { items: QueryList<ListItem>; } Copy the code

Is equivalent to:

@Component({
    selector: 'my-list',
    template: ` 
      
`
}) export class MyListComponent { @ContentChild(ListItem) items: QueryList<ListItem>; } Copy the code

StyleUrls, styles,

  • StyleUrls and styles can be specified at the same time.

  • Priority: template inline Style > styleUrls > styles.

  • Tip: Use styleUrls to refer to external stylesheet files so that the code structure is clearer and easier to manage than styles. Similarly, it is recommended that you use templateUrl to reference the template file.

changeDetection

  • ChangeDetectionStrategy. Default: of every change monitoring components will check all of its internal data (reference object may also depth traversal), in order to get data before and after the change.

  • ChangeDetectionStrategy. OnPush: component change monitoring only check Input attribute (i.e., @ the variables of Input modification) whether the value of the change, when the value of a reference type (Object, Array, etc.), then only the value of reference.

  • Obviously, compared with Default, OnPush reduces the complexity of change monitoring and improves the performance of change monitoring. Using an OnPush strategy on a component is a good choice if the component’s updates depend only on the values of the input properties.

encapsulation

  • ViewEncapsulation.None: No Shadow DOM, and no style wrapping.

  • ViewEncapsulation. Emulated: no Shadow DOM, but by presents to provide style packaging mechanism to simulate the independence of the components, makes the style of the component is not affected by the external, this is the default setting of presents.

  • ViewEncapsulation.Native: Uses the Native Shadow DOM feature.

The life cycle

When Angular creates a component using a constructor, it calls the lifecycle hook methods at specific times in the following order:

Lifecycle hook Call time
ngOnChanges Called before ngOnInit, or when the component enters data (through@InputCalled when those variables explicitly specified by the decorator change.
ngOnInit Called after the first ngOnChanges.It is recommended to get the data at this point, not in the constructor.
ngDoCheck Called each time change monitoring occurs.
ngAfterContentInit Called after embedding external content into the component view, called after the first ngDoCheck and executed only once (for components only).
ngAfterContentChecked Called after ngAfterContentInit, or every time change monitoring occurs (component only).
ngAfterViewInit Called after the component’s view and its child views are created (component only).
ngAfterViewChecked NgAfterViewInit, or called every time a child component changes are monitored (component only).
ngOnDestroy Fired before destroying instructions/components. Resources that are not automatically collected by the garbage collector (Such as subscribed observer events, bound DOM events, timers set with setTimeout or setInterval, and so on) Manually destroy it.

Please indicate the source of reprint, thank you!