避免 writeOut 到 ngModel 的指令 [Angular]

Directive to avoid writeOut to ngModel [Angular]

我想创建一个指令,当它被赋予一个值为 TRUE 的变量时,如果用户更改输入值,它不会将新值写出到吴模型。

使用示例: 指令选择器:d-avoid-change

<input type="text" name="surname" 
    [(ngModel)]="model.surname" 
    [d-avoid-change]="true">

如果来自服务器的姓氏模型是"Foo",用户将其更改为"Bar",model.surname仍然是"Foo",我可以留言给用户。

我正在尝试使用指令的另一种方法,即删除输入并单击 EventListener 这样用户将无法单击,但这看起来像是错误。

我想用它来代替HTML的disabled属性,因为如果我只用[disabled]="true"用户可以打开浏览器 HTML 检查器并更改值并保存,我也不想在服务器上验证这些权限。我对此进行了很多搜索,但找不到任何建议,有人知道我该怎么做吗?

找到了一种方法来构建一个指令,将原始的 NgModel 保存在一个私有变量中,然后如果它接收到 TRUE 的输入参数,它将忽略更改并将原始的NgModel 代替。

它还覆盖了本机 disabled 所以我不需要使用指令和本机 disabled.

指令代码:

import {
    Directive,
    ElementRef,
    AfterViewInit,
    Input,
    AfterContentInit,
    ViewContainerRef,
    Renderer2
} from '@angular/core';
import { NgModel } from '@angular/forms';
import { Observable } from 'rxjs/Observable';

declare let $;

@Directive({
    selector: '[d-disabled]',
    providers: [NgModel]
})
export class DisabledDirective implements AfterViewInit {

    @Input('d-disabled')
    set disabled(disabled: boolean) {
        if (disabled) {
            this.renderer.setAttribute(this.el.nativeElement, 'disabled', 'true');
        } else {
            this.renderer.removeAttribute(this.el.nativeElement, 'disabled');
        }
        this._disabled = disabled;
    }

    _disabled: boolean;
    originalModel: any;

    constructor(private el: ElementRef,
        private ngModel: NgModel,
        private renderer: Renderer2) {
        this.ngModel.valueAccessor.registerOnChange = this.registerOnChange;
        this.ngModel.valueAccessor.registerOnTouched = this.registerOnTouched;

        this.originalModel = this.ngModel;
    }

    ngAfterViewInit() {
        Observable.fromEvent(this.el.nativeElement, 'input')
            .map((n: any) => n.target.value)
            .subscribe(n => {
                if (this._disabled) {
                this.ngModel.viewToModelUpdate(this.originalModel.value);
                this.ngModel.control.patchValue(this.originalModel.value);
                this.ngModel.control.updateValueAndValidity({ emitEvent: true });
            } else {
                    this.onChangeCallback(n);
                }
            });
    }

    private onChangeCallback: (_: any) => void = (_) => { };

    private onTouchedCallback: () => void = () => { };

    registerOnChange = (fn: (_: any) => void): void => { this.onChangeCallback = fn; };
    registerOnTouched = (fn: () => void): void => { this.onTouchedCallback = fn; };

}

使用方法:

<input type="text" name="surname" 
    [(ngModel)]="model.surname" 
    [d-disabled]="true">

如果有人可以帮助我以任何方式改进此方法,但这是我想要的。