【问题标题】:Converting an Angular 1.x directive to Angular 2将 Angular 1.x 指令转换为 Angular 2
【发布时间】:2016-09-11 01:02:38
【问题描述】:

我有一个 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 属性实际上并不存在。如何获取/设置我删除此属性的输入元素的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
        });
    }
}

【问题讨论】:

    标签: angular directive


    【解决方案1】:

    我建议使用 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 属性和主机/DOM 元素的 checked 属性之间设置属性绑定。

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

    使用 Output 属性将更改通知父级是一个不错的方法。

    【讨论】:

    • 谢谢。我知道我在主要教程或开发人员指南中的某处读到了有关 HostBindings 的信息,但没有深入了解。Thisthis 是任何感兴趣的人的相关 api 文档。
    猜你喜欢
    • 2016-10-11
    • 2023-03-21
    • 1970-01-01
    • 2019-04-17
    • 2017-09-20
    • 2015-06-02
    • 2015-04-21
    • 2016-12-29
    • 1970-01-01
    相关资源
    最近更新 更多