【问题标题】:How [class] [attr] [style] directives work[class] [attr] [style] 指令如何工作
【发布时间】:2018-03-19 19:00:22
【问题描述】:

我检查了 ngStyle、ngClass 指令here,但我仍然无法理解它们是如何工作的:

<div [attr.role]="myAriaRole">
<div [class.extra-sparkle]="isDelightful">
<div [style.width.px]="mySize">

内置指令不选择这样的属性:class.extra-sparkle。什么样的selector可以选择这样的html属性?哪个内置指令处理这个?

据我所知,带有点 (style.width.px) 的 html 属性已经不合法了。显然,带有方括号的字符串不直接作为属性传递。但它在哪里完成?哪个指令捕获了这些符号?

【问题讨论】:

    标签: angular angular2-directives


    【解决方案1】:

    以下代码 sn-ps 摘自 Angular.io 文档。

    你指的是Binding target

    <img [src]="heroImageUrl">
    

    第一个 div 引用了Attribute binding

    <table>
        <tr><td [attr.colspan]="1 + 1">One-Two</td></tr>
    </table>
    

    第二个 div 引用了Class binding

    <!-- toggle the "special" class on/off with a property -->
    <div [class.special]="isSpecial">The class binding is special</div>
    
    <!-- binding to `class.special` trumps the class attribute -->
    <div class="special"
         [class.special]="!isSpecial">This one is not so special</div>
    

    但是,建议使用NgClass

    最后一个 div 引用 Style binding。信不信由你,第三个 div 实际上是合法的(或至少在 Angular 中)。

    <button [style.color]="isSpecial ? 'red': 'green'">Red</button>
    <button [style.background-color]="canSave ? 'cyan': 'grey'" >Save</button>
    

    不过,建议改用NgStyle

    因此,在这种情况下,它将变量的值绑定到元素。 (除了class,它将评估isDelightful变量是否为true。)

    <div [attr.role]="myAriaRole"></div>
    <div [class.extra-sparkle]="isDelightful"></div>
    <div [style.width.px]="mySize"></div>
    

    这里有一个Stackblitz demo 供您使用。 :)

    【讨论】:

    • 谢谢@Edrice,这不是我要找的答案,但你让我找到了答案。
    【解决方案2】:

    正如@Edric 指定的here,问题是绑定目标。我首先认为所有这些都是由内置指令处理的

    [attr.role]
    [class.extra-sparkle]
    [style.width.px]
    

    喜欢ngClassngStyle,但事实并非如此。这些都不是指令,它们只是这个的同义词:

    bind-attr.role
    bind-class.extra-sparkle
    bind-style.width.px
    

    并且绑定前缀在模板解析器here 处编译。 “绑定事物”不是指令it is build-in feature that compiler already handles all the bound properties, attributes etc

    【讨论】:

      【解决方案3】:

      你是对的,这些不是指令。

      Angular 编译器为每个带有视图节点的组件创建一个视图工厂。对于每个视图节点,编译器使用位掩码定义一组绑定类型。有不同的binding types,因此在更改检测期间执行不同类型的操作以反映组件类中的更改。

      您可能知道允许更新属性的标准输入机制:

      <div [prop]="myAriaRole">
      

      编译器为其创建TypeProperty 绑定:

      TypeProperty = 1 << 3
      

      因此在更改检测期间使用更新元素属性的操作。

      attr.*class.*style.* 的特殊语法定义了不同类型的绑定:

      TypeElementAttribute = 1 << 0,
      TypeElementClass = 1 << 1,
      TypeElementStyle = 1 << 2,
      

      所以在更改检测期间,每种类型的绑定都会使用相应的操作:

      function CheckAndUpdateElement() {
          ...
          case BindingFlags.TypeElementAttribute -> setElementAttribute
          case BindingFlags.TypeElementClass     -> setElementClass
          case BindingFlags.TypeElementStyle     -> setElementStyle
          case BindingFlags.TypeProperty         -> setElementProperty;
      

      要了解与视图和绑定相关的 Angular 内部结构,我强烈建议您阅读:

      由于在更改检测期间处理了所有绑定,因此请阅读:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-08
        • 1970-01-01
        • 2016-08-26
        • 2020-10-29
        • 1970-01-01
        • 1970-01-01
        • 2016-07-05
        • 2016-12-29
        相关资源
        最近更新 更多