动态更新Angular2指令中自定义属性的值

Dynamically Update value of custom attribute in Angular2 Directive

本文关键字:自定义属性 指令 更新 Angular2 动态      更新时间:2023-09-26

我已经编写了一个指令和一个组件,我需要将值从组件传递到指令,并相应地隐藏元素。简单地说,我试图创建一个类似Angular2中Angular1的ng-show和ng-hide的指令。

headeremu.component.ts

import {Component} from 'angular2/core';
import {DataService} from './data-service.service';
import {ShowHeaderDirective} from './show-header.directive';
@Component({
selector: 'header-menu',
template: `
    <header class="login-header">
    <div class="header-top">
        <div class="container">
          <nav class="navbar navbar-default">
            <div class="container-fluid">
             <div>
                <ul class="nav navbar-nav navbar-right">
                  <li [showHeader]="dispFlag"><a href="javascript:void(0)">Mr. Abc!</a></li>
                  <li><span>|</span></li>
                </ul>
              </div>
            </div><!--/.container-fluid -->
          </nav>
        </div>
    </div>
</header>
`,
directives: [ShowHeaderDirective],
providers:[DataService]
})
export class HeaderComponent {
    dispFlag;
constructor(dataService: DataService){
    this.dispFlag=dataService.headerDisplayFlag;
}
}

显示标题.指令.ts

import {Directive, ElementRef, Renderer, Input} from 'angular2/core';
@Directive({
    selector: '[showHeader]'
})
export class ShowHeaderDirective{
private _el:HTMLElement;
constructor(private el: ElementRef, private renderer: Renderer){
    debugger;
    /* alert(this.el.nativeElement.attributes.showheader.value);
    if(this.el.nativeElement.attributes.showheader.value=="false"){
        this.el.nativeElement.style.display="none";
    } */
}
}

我需要传递从伪服务收集的dataFlag值,并将其发送到指令,指令将相应地显示/隐藏元素。

注意:dataFlag-保持值true/false。

目前我无法从中获得任何输出,因此对代码进行了注释。

我不明白为什么你需要一个自定义指令来隐藏元素,而你有[hidden]属性和*ngIf(你也可以传递函数)。但无论如何,要从属性指令中获取信息,您必须使用@Input()和选择器的名称,如下所示:

export class ShowHeaderDirective implements OnInit{
@Input('showHeader') somealias:boolean;
construct(private el: ElementRef){}
 ngOnInit() {
    if(this.somealias === true){
       //do something with your element
    }
 }

您必须使用OnInit,因为输入值在构造函数中不可用

要将值传递给组件或指令,请使用@Input()

export class ShowHeaderDirective{
  @Input() isHidden:boolean = false;  
  private _el:HTMLElement;
  constructor(private el: ElementRef, private renderer: Renderer){
    debugger;
    /* alert(this.el.nativeElement.attributes.showheader.value);
    if(this.el.nativeElement.attributes.showheader.value=="false"){
        this.el.nativeElement.style.display="none";
    } */
  }
}

并像一样使用它

<li showHeader isHidden="!showHeader"

您也可以使用输入的选择器名称

@Input() showHeader:boolean = false;  

并像一样使用它

<li [showHeader]="!showHeader"

但您也可以使用hidden属性,即所有元素都具有

<li [hidden]="!showHeader"

我尝试了一些东西,也许这将有助于展示我们可以更新Angular中自定义属性的值。

在这里我创建了2个组件app-list-displayapp-list-item-detail的想法是使用前者以列表方式显示数据,当用户单击列表中的任何项目时,会发出一个自定义事件,该事件会触发对主app组件的操作。

app组件然后更改一个变量的值,然后将该变量作为自定义属性提供给另一个app-list-item-detail组件。

这是的代码应用程序列表显示.html

<ul class="list-group" style="float:left margin-left=0px;">
  <li (click)="showItem(item)" *ngFor="let item of items" class="list-group-item list-group-item-action text-justify">{{item.name}}</li>
</ul>

应用程序列表显示。ts

import { Component, OnInit , Input , Output , EventEmitter } from '@angular/core';
@Component({
  selector: 'app-list-display',
  templateUrl: './list-display.component.html',
  styleUrls: ['./list-display.component.css']
})
export class ListDisplayComponent implements OnInit {
  @Input('itemsToBeDisplayed')items:any; 
  @Output('transferItem') transfer = new EventEmitter<{name:string}>();
  constructor() { }
  ngOnInit() {
  }
  showItem(item){
    console.log("in showItem "+JSON.stringify(item,null,2))
    this.transfer.emit(item)
  }
}

app list item detail.html这只是一个示例文本,用于显示用户单击列表中不同项目时数据的变化。

<h4>We are in list detail component
{{showSomething.something}}</h4>

应用程序列表项详细信息.ts这是组件的支持ts文件,表示它具有@Input装饰器显示的自定义属性。

import { Component, OnInit , Input} from '@angular/core';
@Component({
  selector: 'app-list-item-detail',
  templateUrl: './list-item-detail.component.html',
  styleUrls: ['./list-item-detail.component.css']
})
export class ListItemDetailComponent implements OnInit {
  @Input()showSomething:any;
  constructor() { }
  ngOnInit() {
  }
}

现在在app.component.html中,它使用了以上两个组件,如下所示

<app-list-display [itemsToBeDisplayed]="someArrayData" (transferItem)="showSentItem($event)">

<app-list-item-detail [showSomething]="someTxData">
</app-list-item-detail>

如果您注意到app-list-display组件中为自定义事件提供了函数showSentItem。对于另一个组件app-list-item-detail,一个名为someTxData的对象作为自定义属性被注入。这里注入的对象可以通过一个简单的函数调用来更改,这也可以意味着一个简单自定义事件,在我们的情况下,它将是showSentItem

所以现在在app.component.ts

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
 someArrayData = [{name:"John"},{name:"Jane"}];
  someTxData:any;
  showSentItem(item){
    item.something = item.name
    this.someTxData = item;
  } 
}

如果您看到最后一行,this.someTxData将从第一个组件的列表行中获得对象(由于自定义事件),并且该对象将被馈送到第二个组件自定义属性。

因此,理想情况下,一个组件上的自定义事件通过实现者与另一个组件的自定义属性进行对话。

抱歉回答太长。