乐趣区

关于angular:Angular-巧用component装饰器属性

带有 @Component() 装璜器的 TypeScript 类是 Angular 组件组成十分重要的一部分,罕用的属性有以下几种

  1. selector:CSS 选择器,用于定义如何在模板中应用组件
  2. template 或者 templateUrl: HTML 模板
  3. styles 或 styleUrls: 一组可选的 CSS 款式

还有一些不太罕用的属性,咱们一起来看看有哪些。

changeDetection

应用形式:

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})

changeDetection 用于给以后组件定义变更检测策略,当组件实例化之后,Angular 就会创立一个变更检测器,它负责流传组件各个绑定值的变动。源码中它的值为:changeDetection?: ChangeDetectionStrategy,咱们再来看看源码中 ChangeDetectionStrategy 是如何定义的

export declare enum ChangeDetectionStrategy {
    OnPush = 0,
    Default = 1
}

Default : 变更策略为 CheckAlways,默认值。
这个没什么好说的,始终检测,即便组件内的属性和 @Input 属性都没有变动,也会一直检测变更
OnPush : 变更策略为 CheckOnce(按需)。
应用 ChangeDetectionStrategy.OnPush 也是优化性能的一种办法,毕竟它是按需检测嘛,不会不停的检测,然而应用它是有严格的条件的,不然一不小心就产生 bug 了,如果业务满足以下条件,能够放心使用:

  • 组件的视图变动仅仅依赖 @Input 属性的变动,如果有依赖组件自身的属性则不能够
  • @Input 属性为非对象的时候,或者为对象的时候的每次 @Input 属性的扭转是扭转对象自身的形式(eg: obj = xxx ),而不是扭转援用的形式( eg: obj.propertyName = xxx )。

如果 @Input 属性的扭转是扭转援用的形式,还是想触发视图检测更改,还能够应用 ChangeDetectorRef 手动触发变更。哈哈,感觉越讲越多,changeDetection 能够独自写一篇了,如果大家有须要理解的,我再独自开一篇。好了,the next one~

viewProviders

提到这个就须要理解 依赖注入 ,然而对于DI 须要学习的十分多,值得独自解说,本章的重点不是 DI,所以不会讲太多。
viewProviders 在源码中的值为:viewProviders?: Provider[]; 示意定义一组仅在视图可用的 Provider 对象
留神:前提是该对象没有被注入到根模块,或者组件所在的模块,不然定义 viewProviders 显得毫无意义,如下咱们有一个 ServiceDemo service

@Injectable() // 留神这里不能加上 {providedIn: 'root'} 不然就注入到根模块了,到处都能够应用
export class ServiceDemo {...}

咱们把 ServiceDemo 退出 ChildComponent 组件的 viewProviders ServiceDemo 既没有被注入根模块也没有被注入 ChildComponent 所在的模块

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.scss'],
  viewProviders: [ServiceDemo]
})
export class ChildComponent implements OnInit {...}

咱们只能在 ChildComponent 的视图应用 ServiceDemo 的属性或者办法,如果在组件内应用就会报错。

providers

接以上,如果咱们想在 ChildComponent 的视图和组件内应用 ServiceDemo 的属性或者办法,或者仅在组件内应用,则应该把它退出 providers,如下:

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.scss'],
  providers: [ServiceDemo]
})
export class ChildComponent implements OnInit {...}

应用 viewProviders 或者 providers,目标是只把 provider 对象注入到某个组件或者组件视图,这样的 provider 对象肯定是小范畴内应用的封装对象,防止注入到根模块影响首屏加载。

encapsulation

用于定义 Component 的模板和款式封装选项。encapsulation 在源码中的值为 encapsulation?: ViewEncapsulation,来看看 ViewEncapsulation 如何定义的

export declare enum ViewEncapsulation {
    Emulated = 0, // 默认
    Native = 1, // 已废除
    None = 2,
    ShadowDom = 3
}
  • Emulated:这是默认选项,会向 Host 元素增加 _nghost-xxx-xxx ,非 Host 元素增加 _ngcontent-xxx-xxx 属性模仿原生选择器,用来代替 class id ,以隔离组件的款式不影响内部,组件内定义的款式作用域仅在该组件。

    <app-parent _nghost-uvk-c19>
      <h1 _ngcontent-uvk-c19>parent component</h1>
      <p _ngcontent-uvk-c19>parent works!</p>
      <app-child _ngcontent-uvk-c19 _nghost-uvk-c20>
        <p _ngcontent-uvk-c20>child works</p>
      </app-child>
    </app-parent>
    
  • None:不提供任何模板或款式封装,意味着该组件内的款式会被增加到全局,利用到整个document
  • ShadowDom:应用原生的 Shadow DOM 个性封装,并为组件的 Host 元素创立 ShadowRoot,组件款式将不受全局款式影响,组件内定义的款式作用域限定为该 Shadow DOM。应用了 ShadowDom 组件的子组件也会利用到该组件款式,因为子组件也在 ShadowRoot

interpolation

改写默认的插值表达式起止分界符({{和}})。它的值定义为 interpolation?: [string, string]

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.scss'],
  interpolation: ['(', ')']
})

如果你不喜爱应用 {{value}} 这样的插值形式,能够改成你喜爱的形式 eg: (value)

preserveWhitespaces

它的值为 Boolean,默认为 false,编译后的模板中移除可能多余的空白字符。空白字符就是指那些能在 JavaScript 正则表达式中匹配 \s 的字符。为 true 则保留。

entryComponents

一个组件的汇合,它应该和以后组件一起编译。对于这里列出的每个组件,Angular 都会创立一个 ComponentFactory 并保留进 ComponentFactoryResolver 中, 官网的解释,是不是看完还是不晓得是干嘛的?跟我一起理解一下

假如你在我的项目定义了一些组件,这些组件编译工具没有辨认进去它在我的项目中有应用,Tree Shaking 工具就会把这些组件从最终的代码包中摘出去。然而其实这些组件可能是 路由组件 或者是 动静加载 的,必须把它们显式增加到 entryComponents 中,路由组件须要增加到 @NgModuleentryComponents 中,动静加载的组件看它的应用范畴,如果仅仅在一两个组件内应用了,能够把它们退出组件的 entryComponents

animations

用来引入定义动画的触发器,须要联合 @angular/animations 应用,本章就不重点解说

moduleId

蕴含该组件的那个模块的 ID。在应用 CommonJS 作为模块化工具的时候用失去,angular 应用的是 es6 模块化语法,日常开发预计用不到这个属性。

还有一些继承自 Directive 装璜器的属性,下篇咱们持续~~~。
喜爱就点个赞吧~~~

退出移动版