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

Converting an Angular 1.x directive to Angular 2

我有一个 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 属性实际上并不存在。我怎样才能 get/set 放置此属性的输入元素的 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
        });
    }
}

我建议使用 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 事件之间设置事件绑定。

使用输出 属性 将更改通知父级是一个好方法。