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

时间:2016-04-30 13:47:23

标签: javascript angular ecmascript-6

我编写了一个Directive和一个Component,我需要将Component中的值传递给指令,并相应地隐藏元素。 简单来说,我试图创建一个类似于Angular2中Angular1的ng-show和ng-hide的指令。

headermenu.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;
}
}

显示-header.directive.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。

目前我无法从中获取任何输出,因此对代码进行了评论。

3 个答案:

答案 0 :(得分:1)

为了能够将值传递给组件或指令,请使用@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"

答案 1 :(得分:1)

我不明白为什么你需要一个隐藏元素的自定义指令,同时你有[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,因为输入值在构造函数

中不可用

答案 2 :(得分:1)

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

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

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

这是代码 应用一览display.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>

应用一览display.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>

app-list-item-detail.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从第一个组件的列表行中获得了对象(感谢自定义事件),并且同一个对象被送入第二个组件自定义属性。

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

为长期答案道歉。