【问题标题】:How to change border using a structural directive?如何使用结构指令更改边框?
【发布时间】:2019-02-04 01:49:25
【问题描述】:

我正在尝试创建一个执行两件事的角度指令。

 1. change border of the host element
 2. append a button at the end of the host element

到目前为止,我正处于必须设置宿主元素边框的第一步。

HTML

  <div *myDirective
        <h1> some value </h1>
  </div>      

指令

export class MyDirective{

  constructor(private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef) {
      this.templateRef.elementRef.nativeElement.style['border'] = '1px solid red';
      this.viewContainer.createEmbeddedView(this.templateRef);
    }      
}

现在当我将此指令添加到 div 元素时,我收到以下错误,

Cannot set property 'border' of undefined

如何更改样式并使用结构指令将另一个元素附加到主机?

[编辑] 由于大多数答案都建议我创建一个属性指令,所以我只想从角度文档中发布关于结构指令的声明。

它们塑造或重塑 DOM 的结构,通常是通过添加、移除或操作元素。

在这种情况下,创建属性指令以将按钮附加到宿主元素是不合适的。不是吗?

【问题讨论】:

  • 你不应该使用ElementRef而不是TemplateRef吗?

标签: angular angular-directive


【解决方案1】:

试试这样:

DEMO

mydirective.ts:

import { Directive, TemplateRef, ElementRef, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[appMydirective]'
})
export class MydirectiveDirective {

  constructor(private el: ElementRef) {
    console.log(this.el.nativeElement)
    el.nativeElement.style.border = '2px solid red';
    let bt = document.createElement("button");
    var btContent = document.createTextNode("my Button");
    bt.appendChild(btContent);
    bt.style.cssFloat = 'right'
    this.el.nativeElement.append(bt)
  }
}

HTML:

<div appMydirective>
        <h1> some value </h1>
  </div> 

【讨论】:

    【解决方案2】:

    确实,我会为此使用结构指令。

    但是templateRef.elementRef.nativeElement只是一个html注释,并没有style属性。

    要附加按钮,您可以遵循这个非常好的结构指令示例: Adding a Component to a TemplateRef using a structural Directive

    【讨论】:

      【解决方案3】:

      对于边框,您需要执行以下操作:

      创建指令:

      import { Directive, ElementRef, Renderer } from '@angular/core';
      
      // Directive decorator
      @Directive({ selector: '[myDirective]' })
      // Directive class
      export class MyDirective {
          constructor(el: ElementRef, renderer: Renderer) {
          // Use renderer to render the element with styles
          renderer.setElementStyle(el.nativeElement, 'border', '1px solid red');
          }
      }
      

      接下来需要通过 SharedModule 声明和导出该指令,以便应用模块可以全局加载和导入。

      共享模块

      import { NgModule } from '@angular/core';
      
      import { MyDirective } from './my-directive.directive';
      
      @NgModule({
          declarations: [
              MyDirective
          ],
          exports: [
              MyDirective
          ]
      })
      export class SharedModule{}
      

      然后在app.module中导入共享模块

      然后按如下方式使用:

      <div myDirective>
          <h1> some value </h1>
      </div> 
      

      Demo

      【讨论】:

      • 根据 Angular 文档添加、删除操作 DOM 我们需要使用结构指令。但是您创建的是一个属性指令。这不是反模式吗?
      • 根据documentation,“属性指令改变了 DOM 元素的外观或行为”。如果您想使用指令来应用 css,那么这是要走的路,而对于应用边框,这就是您正在做的事情。在角度文档中,他们应用了高亮效果,这又是一个 css 更改,所以我没有看到反模式。
      • 因为我还有一个要求,我必须在宿主元素的末尾添加按钮,所以我不能使用属性指令。
      猜你喜欢
      • 2020-09-13
      • 2021-08-04
      • 1970-01-01
      • 1970-01-01
      • 2014-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-20
      相关资源
      最近更新 更多