9

我正在使用 Angular 2.0 最终版本。

我想做的事? - 我只想在输入接收焦点时显示一些通知(警告,输入要求)。或者更好的是,当他的父母 ( the div) 有mouse hover事件时。

从父级(div)执行此操作很容易。只需 (focus)=showNotifications() + 一个 ngIf - 就完成了。

但我想将此功能封装在 show-notifications 组件中 - 并使其可重用..

鉴于我the control使用 - 在显示通知内部传递@Input()- 如果我可以访问native HTML input element.You 可以看到如何在show-notifications.component.ts. 这是代码:

app.component.html:

`<div>
   <label>Name: </label>
   <input formControlName="myName">
   <show-notifications [the_control]="myName" ></show-notifications>
</div>`

app.component.ts:

export class AppComponent {
    myName = new FormControl("defaultvalue",[some validators..])
}

显示通知.component.html:

<div class="show_requirements" *ngIf="hasfocus or parentDivHasMouseHover"> // incorect code and logic - i know, but you can see the idea..

    <p *ngFor="let requirement of thisInputRequirements">{{requirement}}<p>

</div>

显示通知.component.ts:

export class ShowNotificationsComponent {

    @Input() the_control;
    this.thisInputRequirements = // take them form firebase.
    this.thisInputCustomErrorMessages = // take them from firebase.

    // I implemented all this and works amazing but i want to do:

    //something like this:

    ngOnInit(){
        this.nativeInputElement = this.the_control.getNativeElement() // this of course doesn't work

        // the requirements are shown only when the input receive focus
        let source = Rx.DOM.focus(this.nativeInputElement);
        source.subscribe( x => this.hasFocus = true)

        // Or even better: 
        // the requirements are shown only when the parent has mouse hover
        // or any other event / endles posibilites here..

        let parent = getParentOf(this.nativeInputElement)
        let source = Rx.DOM.mouseover(parent);
        source.subscribe( x => this.parentDivHasMouseHover = true) // this will be some toggling functionality.
    }

}

问题:

鉴于我有 formControl (myName = the_control) 对象,我如何访问本机元素?

有没有更好的方法在单独的组件中进行通知 - 并使其可重用?我已经在整个应用程序中成功使用了它 - 显示错误和输入要求..

注意:我尝试首先使用主题标签语法(#myInput)传递洞 html 输入并在那里形成,在 show-notifications 组件内,我尝试执行:myInput.myName - 访问控件但我未定义。本机输入元素上不存在这些控件。我需要该控件进行验证:)

4

4 回答 4

4

我认为您可以使用#符号将元素传递给ShowNotificationsComponent

export class ShowNotificationsComponent {
    @Input() the_control;
    @Input() elm;
    //...
}

然后在模板中:

<input formControlName="myName" #elm>
<show-notifications [the_control]="myName" [elm]="elm"></show-notifications>
于 2016-09-30T09:09:13.953 回答
0

从根本上说,元素访问其兄弟元素的唯一方法是传递对它的引用。您可以为您的通知组件提供控件和表单的名称并进行查找,就像您正在做的那样,但这是一个容易出错的过程。但是,我认为创建指令对解决您的情况更有帮助。您可以直接在输入上使用该指令。它允许您的代码像组件一样可重用,但因为它实际上是在输入上,所以它可以访问本机 html 元素。这是一个使用我编写的货币输入的示例,以了解该做什么。我为焦点事件添加了一个位置,以向您展示在哪里做事。显然,您想更改名称并使用小数管道擦除代码,但我将其留作参考。

@Directive({
  selector: '[appCurrencyInput]',
})
export class CurrencyInputDirective implements OnInit {
  @Input() runOnEveryModelChange = false;

  public reference: ElementRef<HTMLInputElement>;
  private numTimesRan = 0;
  constructor(el: ElementRef, private decimalPipe: DecimalPipe) {
    this.reference = el;
  }

  @HostListener('focus', ['$event'])
  private onFocus = (focusEvent: FocusEvent) => {
    //You could do showNotifications() here, have access to focusEvent if you want
  }

  @HostListener('ngModelChange', ['$event'])
  private onModelChange = (ngModelChangeEvent: number) => {
    this.numTimesRan++;
    if (this.runOnEveryModelChange || this.numTimesRan === 1) {
      const asNumber = this.decimalPipe.transform(ngModelChangeEvent, '1.2-2');
      this.reference.nativeElement.value = asNumber ? asNumber.replace(/,/g, '') : null;
    }
  };

  ngOnInit() {
    //here you could do something if you want, just like a component
  }
}

你会像这样使用它

<input formControlName="myName" appCurrencyInput>
于 2021-11-17T14:25:55.883 回答
0

如果您想从 Abstractcontrol 获取一些信息,因为它是一个普通的 Html 输入元素,我发现一些可能会有所帮助,例如,如果您想向其添加“事件侦听器”,以便了解用户何时与之交互元素,它可以通过使用 valueChanges 或 statusChanges 来完成,这两个 Observables 都来自 AbstractControl 类,我用它来知道元素何时发生变化,并在提交表单之前选择选项以执行更多操作,我将代码留在这里例子:

getValue() {
  this.myForm.get('myControlName').valueChanges.subscribe((optionValue) => {
    console.log(optionValue);
    this.doSomething(optionValue);
  });
}

如果您想在用户悬停父级时制作一些动画或更改,也许您可​​以使用一些简单的 CSS 技巧,如下所示:

.parent #child{
  opacity: 0;
}

.parent:hover #child{
  opacity: 1;
}

您可以查看此文档以获取更多详细信息:https ://angular.io/api/forms/AbstractControl#valueChanges

于 2020-02-06T17:23:46.050 回答
-3

这是非常基本的。FormContrl 不是必需的。您应该使用 # 在输入元素上创建一个局部变量并将局部变量传递给方法

<div>
<label for="firstname">First Name</label>
<input name="fname" #nameFirst />
<label for="lastname">Last Name</label>
<input name="lname" #nameLast />
</div>
<button (click)="send(nameFirst , nameLast)">Submit</button>

export class HtmlExample {

    send(firstName: HTMLInputElement, lastName: HTMLInputElement): void {
        console.log(`Hello ${firstName.value}  ${lastName.value}`);
        firstName.value = '';
        lastName.value = '';
    }

}
于 2017-05-11T12:39:37.843 回答