Angular2 - 指令选择器

时间:2016-03-31 17:35:07

标签: angularjs angularjs-directive angular

我正在使用最新的Angular 2 beta(45?)并尝试将ngClass附加到指令选择器标识的元素。用于切换类的变量不会更新。

我怀疑这是两件事之一:

  1. Angular2就是不行,所以这是一个范围问题;如果我 将一个div放在指令选择器元素内并附加 ngClass到那个div,它的工作原理。我不想这样做。
  2. 因为我对窗户事件作出反应。我尝试过使用Observers, setTimeout hackery和zone。没有运气。
  3. 有没有办法做我想做的事情?那不就是这样吗?

    从内存写入的示例代码,因为我目前无法访问它:

    @Directive({
        selector: "nav",
        templateUrl: "templates/nav.html"
    });
    
    export class NavComponent {
        isOpen:Boolean = false;
    
        onScroll(e) {
            this.isOpen = true;
        }
    
        window.onscroll = (e) => this.onScroll.call(this);  // .call seemed necessary, because otherwise the scope of 'this' changed to window instead of the directive  
    }
    

    以下内容不起作用:

    的index.html

    <nav [ngClass]="{open: isOpen}"></nav>
    

    模板/ nav.html

    <a href="#">whatever</a>
    ...
    <a href="#">whatever 2</a>
    

    以下工作正常:

    的index.html

    <nav></nav>
    

    模板/ nav.html

    <div [ngClass]="{open: isOpen}">
        <a href="#">whatever</a>
        ...
        <a href="#">whatever 2</a>
    </div>
    

2 个答案:

答案 0 :(得分:2)

除了Günter的答案,使用host listener而不是为window.onscroll分配事件处理程序。然后运行角度变化检测并在滚动时实际更新CSS类。 (否则,在视图更新之前需要执行其他一些事件。)

@Component({
    selector: "nav",
    template: `<a href="#">whatever</a>
      <a href="#">whatever 2</a>`,
    host: {
      '(window:scroll)': 'onScroll($event)',   //  <<------
      '[class.open]': 'isOpen'
    }
})
export class NavComponent {
  isOpen:Boolean = false;
  onScroll(e) {
    this.isOpen = true;
  }
}

@Component({
  selector: 'my-app',
  template: `<nav></nav>
    <div *ngFor="#row of dummyArray; #i = index">row {{i}}</div>`,
  styles: ['.open { background-color: lightblue }']
  directives: [NavComponent]
})
export class AppComponent {
  dummyArray = new Array(100);
  constructor() { console.clear(); }
}

Plunker

答案 1 :(得分:1)

中的

isOpen

<nav [ngClass]="{open: isOpen}"></nav>

指的是<nav>的父组件,其模板中包含<nav>的组件。

如果要在指令主机上设置类,请使用

@Directive({
    selector: "nav",
    templateUrl: "templates/nav.html",
    host: {'[class.open]': 'isOpen'}
});
export class NavComponent {
    isOpen:Boolean = false;

    onScroll(e) {
        this.isOpen = true;
    }
}