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

标签 angular directive

我有一个包含一些小部件的包装引导模板,我正在尝试将其转换为 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 属性实际上并不存在。如何获取/设置放置此属性的输入元素的 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 属性的双向数据绑定(bind)。这样,您就不需要使用 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 属性和主机/DOM 元素的 checked 属性之间设置属性绑定(bind)。

HostListener在指令的 onChange() 方法和主机/DOM 元素的 change 事件之间设置事件绑定(bind)。

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

关于angular - 将 Angular 1.x 指令转换为 Angular 2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37233598/

相关文章:

angular - 成功构建Angular后需要将dist文件夹复制到另一个文件夹

javascript - 从前端调用 Electron 方法

angular - Angular2 的管道如何与数据绑定(bind)一起工作?

javascript - Angularjs:如何将范围变量传递给指令?

angularjs - Controller 'ngModel' ,指令 '…' 需要,无法找到

javascript - Angular 项目 : How to get instance of secondary firebase app?

session - Spring Security session JSESSIONID

javascript - 指令 templateUrl 重定向到/

javascript - Angular 指令不适用于 *ngIf。从组件调用指令

templates - Angular js 指令动态模板绑定(bind)