将Angular 1.x指令转换为Angular 2

时间:2016-05-15 01:31:32

标签: angular directive

我有一个带有几个小部件的wrap-bootstrap模板,我试图转换为Angular 2.这个让我难过:

.directive('changeLayout', function(){

    return {
        restrict: 'A',
        scope: {
            changeLayout: '='
        },

        link: function(scope, element, attr) {

            //Default State
            if(scope.changeLayout === '1') {
                element.prop('checked', true);
            }

            //Change State
            element.on('change', function(){
                if(element.is(':checked')) {
                    localStorage.setItem('ma-layout-status', 1);
                    scope.$apply(function(){
                        scope.changeLayout = '1';
                    })
                }
                else {
                    localStorage.setItem('ma-layout-status', 0);
                    scope.$apply(function(){
                        scope.changeLayout = '0';
                    })
                }
            })
        }
    }
})

我启动了一个新指令(如下所示),但HtmlElement对象的isprop属性实际上并不存在。如何获取/设置我删除此属性的input元素的checked属性?我还认为该指令通过Output属性公开布局状态,因此父组件可以相应地做出响应。

有人可以指导我一点吗?我是在正确的轨道上吗?谢谢!

新指令:

import { Directive, ElementRef, Output, EventEmitter, OnInit } from '@angular/core';

import { LocalStorage } from "../common";

@Directive({
    selector: '[change-layout]',
    host: {
        '(change)': 'onChange()'
    }
})

export class ChangeLayoutDirective implements OnInit {

    private el: HTMLElement;
    @LocalStorage() public layoutStatus: Number = 0;

    @Output() layoutStatusChange = new EventEmitter();

    constructor(el: ElementRef) {
        this.el = el.nativeElement;
    }

    ngOnInit() {
        this.el.prop('checked', false);
        if(this.layoutStatus === 1) {
            this.el.prop('checked', true);
        }
    }

    onChange() { this.toggleLayout(); }

    private toggleLayout() {
        if(this.el.is(':checked')) {
            this.layoutStatus = 1;
        }
        else {
            this.layoutStatus = 0;
        }
        this.layoutStatusChange.emit({
            value: this.layoutStatus
        });
    }
}

1 个答案:

答案 0 :(得分:2)

我建议使用HostBinding和HostListener设置对主机元素的checked属性的双向数据绑定。这样,您就不需要使用ElementRef或nativeElement。

export class ChangeLayoutDirective implements OnInit {
  private layoutStatus = 0;
  @Output() layoutStatusChange = new EventEmitter();
  @HostBinding('checked') checked = false;
  @HostListener('change', ['$event.target.checked'])
  onChange(checked) { 
    console.log('checked =', checked);
    this.toggleLayout(checked); 
  }
  ngOnInit() {
    if(this.layoutStatus === 1) {
      this.checked = true;
    }
  }
  private toggleLayout(checked) {
    this.layoutStatus = checked ? 1 : 0;
    this.checked = checked;
    this.layoutStatusChange.emit({
      value: this.layoutStatus
    });
  }
}

Plunker

HostBinding设置指令的checked属性与host / DOM元素的checked属性之间的属性绑定。

HostListener设置指令的onChange()方法与host / DOM元素的change事件之间的事件绑定。

使用Output属性通知父级更改是一种很好的方法。