【问题标题】:Build single directive to perform both Structural & Attribute behaviour?构建单个指令来执行结构和属性行为?
【发布时间】:2017-10-11 20:31:04
【问题描述】:

我正在尝试构建一个 Angular 指令,我想根据一些配置输入值实现以下目标

  1. 根据输入值在 DOM 中添加元素。 (就像 ngIf)
  2. 如果元素呈现,则为其添加一些样式
  3. 向元素添加一些属性属性,例如disabled

根据我对 Angular 的一点点了解和理解,我们可以使用Structural Directive 实现第一个要求。至于第二和第三个要求,我们需要创建Attribute Directive。这是我对这两个指令的实现

import { SomeService } from './some.service';
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({ selector: '[structuralBehaviour]' })
export class StructuralBehaviourDirective {

    constructor(private templateRef: TemplateRef<any>,
        private viewContainer: ViewContainerRef, private someService: SomeService) { }

    @Input() set structuralBehaviour(config: any) {

        // 1st Condition
        // Conditional Stamentents using config and somService
        // For the purpose to decide whether to add template in
        // DOM or not
        this.viewContainer.createEmbeddedView(this.templateRef);

   }
}

这里是属性指令

import { SomeService } from './some.service';
import { Directive, ElementRef, Input, Renderer } from '@angular/core';

@Directive({ selector: '[attributeBehaviour]' })
export class AttributeBehaviourDirective {

    constructor(private _renderer: Renderer, private _el: ElementRef,
    private someService: SomeService) { }

    @Input() set attributeBehaviour(config: any) {

        // 2nd Condition
        // Conditional Stamentents using config and someService
        // For the purpose to set style visibility property to hidden
        this._el.nativeElement.style.visibility = 'hidden';

        // 3rd Condition
        // Conditional Stamentents using config and someService
        // For the purpose to add disabled attribute
        this._renderer.setElementProperty(this._el.nativeElement, 'disabled, true);

    }
}

目前,我正在使用上述指令,如下所示,对我来说效果很好

<button *structuralBehaviour="config" [attributeBehaviour]="config"
 class="btn btn-primary">Add</button> 

我在这里寻找的是问题的答案,是否可以将上述两个指令合并在一起并从中构建单个指令,以便我可以使用它们这样的东西

<button *singleBehaviour="config" class="btn btn-primary">Add</button> 

【问题讨论】:

  • Ajax,您使用的是 jQuery,还是可以将它包含在您的项目中? jQuery 可以快速解决您的问题。
  • 不,我没有使用 JQuery,尝试仅使用 Angular Typescript 代码来实现它。

标签: angular typescript angular-directive


【解决方案1】:

this.viewContainer.createEmbeddedView 返回包含rootNodesEmbeddedViewRef。你可以用它来实现你的行为

@Directive({ selector: '[singleBehaviour]' })
export class SingleBehaviourDirective {
  constructor(
    private templateRef: TemplateRef<any>,
    private _renderer: Renderer2,
    private viewContainer: ViewContainerRef) { }

  @Input() set singleBehaviour(config: any) {
    let view = this.viewContainer.createEmbeddedView(this.templateRef);
    let rootElem = view.rootNodes[0];
    if(rootElem) {
      rootElem.style.visibility = 'hidden';
      this._renderer.setProperty(rootElem, 'disabled', true);
    }
  }
}

Plunker Example

【讨论】:

  • 是的,这就是我要找的。​​span>
【解决方案2】:

我打算写这篇评论,但担心超过 500 个字符。

对于您的第一个问题,请查看here

第二个,试试this

第三个,类似于第二个超链接,而不是.css() 使用.attr('attrName', 'attrVal')。或者,尝试实现,this

这些可能有帮助,也可能没有帮助,它们是一些快速谷歌搜索的结果。第二个超链接坚持将 .css() 包装到 angularJS 框架中并且可以在不将 jQuery 包含在单独的脚本标记中的情况下使用。我不确定是否确实如此,因此里程可能会有所不同。祝你好运!

【讨论】:

  • 感谢您的回答。该解决方案适用于 jQuery,但我正在寻找的是基于 Angular(v4) Typescript 的解决方案。
猜你喜欢
  • 2019-04-08
  • 2017-05-16
  • 1970-01-01
  • 1970-01-01
  • 2021-05-30
  • 2020-06-27
  • 1970-01-01
  • 2020-12-27
  • 2019-04-27
相关资源
最近更新 更多