【问题标题】:reference peer(edit: parent) directive input参考对等(编辑:父)指令输入
【发布时间】:2025-11-24 12:00:01
【问题描述】:

我打算使用元数据来设置 HTML 输入属性。按照属性指令指南 (https://angular.io/docs/ts/latest/guide/attribute-directives.html) 我想出了以下内容。

import "reflect-metadata";
import { Directive, ElementRef, Input, OnInit} from '@angular/core';

@Directive({
    selector: '[myModel]'
})
export class ModelDirectives implements OnInit {

    private element: any;

    @Input('myModel')
    model: any;

    @Input('myProperty')
    propertyString: string;

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

    ngOnInit() {
        if (this.model.hasOwnProperty(this.propertyString)) {
            this.element.required = Reflect.getMetadata('required', this.model, this.propertyString);
            //TODO other metadata
        }
    }
}

如果我使用此指令,以下输入标签将具有必需的属性。
<input type="text" placeholder="Email" [(ngModel)]="model.username" name="username" [myModel]="model" [myProperty]="'username'" />
但是使用material2就不行了。
<md-input type="text" placeholder="Email" [(ngModel)]="model.username" name="username" [myModel]="model" [myProperty]="'username'"></md-input>
我看到材质输入组件有一个必需的@Input (https://github.com/angular/material2/blob/master/src/components/input/input.ts#L159),它传递给本机输入标签。我的问题是如何从我的指令中引用该对等指令的输入?还是我走对了?

注意:用户名属性定义为

@required()
public username: string;

在哪里

/**
 * Property decorator for form models.
 * @param isRequired Whether property is required for html form, defaults to true.
 */
export function required(isRequired?: boolean): PropertyDecorator {
    return Reflect.metadata('required', isRequired ? isRequired : true);
}

【问题讨论】:

    标签: javascript html angular angular2-directives


    【解决方案1】:

    所以我发现我的[myModel] 指令将被视为md-input 的子代而不是angular2 依赖注入中的对等,所以我使用了以下https://angular.io/docs/ts/latest/cookbook/dependency-injection.html#!#find-parent

    import "reflect-metadata";
    import { Directive, ElementRef, Input, OnInit, Optional } from '@angular/core';
    import { MdInput } from '@angular2-material/input';
    
    @Directive({
        selector: '[tstModel]'
    })
    export class ModelDirectives implements OnInit {
    
        private inputElement: HTMLInputElement;
    
        @Input('tstModel')
        model: any;
    
        @Input('tstProperty')
        propertyString: string;
    
    
        constructor(elementRef: ElementRef, @Optional() private mdInput: MdInput ) {
            this.inputElement = elementRef.nativeElement;
        }
    
        ngOnInit() {
                this.mdInput.required = Reflect.getMetadata('required', this.model, this.propertyString);
            }
        }
    
    }
    

    【讨论】: