页面加载或显示/隐藏部分以更新模型值

发布于 2025-02-10 19:33:59 字数 1651 浏览 1 评论 0原文

我有一个为大写速度转换为大写的angualr指令(我知道有一个角管为此,但是我创建了此指令来理解概念。我实际上想要其他指令的类似功能)。但是由于某种原因,该指令最初并未为预定义的模型值调用。但是,当我手动更新输入文本框时,这将触发。

我希望Angular指令在页面加载上运行或显示组件的显示/隐藏部分。

在此示例中,我想在页面加载中预先填充带有“ test”的“用户名”文本框,或者显示组件的“显示/隐藏”部分(此显示/隐藏部分将根据服务调用的响应显示或隐藏)因为我用“测试”初始化了模型值,并定义了appuppercase输入文本框上的指令。

我们如何告诉Angular指令在页面加载上运行或显示组件的“隐藏”部分。

这是appuppercase指令,

@Directive({
  selector: '[appUpperCase]'
})
export class UpperCaseDirective implements OnInit {

  constructor(private control: NgControl) { }

  processInput(value: any) {
    return value.toUpperCase();
  }

  @HostListener('ngModelChange', ['$event'])
  ngModelChange(value: any) {
    console.log(`directive called ${value}`);
    this.control.valueAccessor.writeValue(this.processInput(value));
  }

  @HostListener('keydown.backspace', ['$event'])
  keydownBackspace(value: any) {
    this.control.valueAccessor.writeValue(this.processInput(value));
  }

  ngOnInit(): void {
  }

}

这是我的html文件:

<form novalidate (ngSubmit)="submitForm()">
    <div class="form-group row">
      <label for="UserName" class="col-2 col-form-label">User Name:</label>
      <div class="col-4">
      <input class="form-control" id="UserName" name="userName" required [(ngModel)]="userName" appUpperCase>
      Model: {{ userName }}
      </div>
    </div>

  <button class="btn btn-primary" type="submit">
      Search
    </button>
  </form>

在组件文件中。

 userName: any;
  constructor() {
    this.userName = 'test';
  }

I have an angualr directive created to convert lowerCase to UpperCase (I know there is an angular pipe for this, but I created this directive to understand the concepts. I actually want similar kind of functionality for other directive). But for some reason, this directive is not called initially for pre-defined model value. However, this is triggered when I update the input text box manually.

I wanted an angular directive to run on page load or show/hide section of the component.

In this example, I wanted to pre-populate the "User Name" text box with "TEST" on page load or show/hide section of the component (this show/hide section will show or hide based on the response from the Service call) because I initialized model value with "test" and defined appUpperCase directive on input text box.

How do we tell angular directive to run on page load or show/hide section of the component.

Here is the appUpperCase directive

@Directive({
  selector: '[appUpperCase]'
})
export class UpperCaseDirective implements OnInit {

  constructor(private control: NgControl) { }

  processInput(value: any) {
    return value.toUpperCase();
  }

  @HostListener('ngModelChange', ['$event'])
  ngModelChange(value: any) {
    console.log(`directive called ${value}`);
    this.control.valueAccessor.writeValue(this.processInput(value));
  }

  @HostListener('keydown.backspace', ['$event'])
  keydownBackspace(value: any) {
    this.control.valueAccessor.writeValue(this.processInput(value));
  }

  ngOnInit(): void {
  }

}

Here is my html file:

<form novalidate (ngSubmit)="submitForm()">
    <div class="form-group row">
      <label for="UserName" class="col-2 col-form-label">User Name:</label>
      <div class="col-4">
      <input class="form-control" id="UserName" name="userName" required [(ngModel)]="userName" appUpperCase>
      Model: {{ userName }}
      </div>
    </div>

  <button class="btn btn-primary" type="submit">
      Search
    </button>
  </form>

and in component file.

 userName: any;
  constructor() {
    this.userName = 'test';
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

墟烟 2025-02-17 19:33:59

我真的不明白您为什么使用hostListener(首先,对于keydown.backspace侦听器,您不会在侦听器中收到值,而是事件)。

为什么不只是听控件的Valuechanges流并在此处更新它呢?

另外,您应该使用ReactiveFormSModule,以便获得值。

// directive.ts

import { Directive, OnDestroy, OnInit } from '@angular/core';
import { NgControl } from '@angular/forms';
import { Subject } from 'rxjs';
import { distinctUntilChanged, startWith, takeUntil } from 'rxjs/operators';

@Directive({
  selector: '[appUpperCase]',
})
export class UpperCaseDirective implements OnInit, OnDestroy {
  private _destroyed$ = new Subject<void>();

  constructor(private control: NgControl) {}

  processInput(value: any) {
    return value.toUpperCase();
  }

  ngOnDestroy(): void {
    this._destroyed$.next();
    this._destroyed$.complete();
  }

  ngOnInit(): void {
    this.control.valueChanges
      .pipe(
        startWith(this.control.value),
        distinctUntilChanged((first, second) => {
          return this.processInput(first) === this.processInput(second);
        }),
        takeUntil(this._destroyed$)
      )
      .subscribe((value) => {
        this.control.control.setValue(this.processInput(value));
      });
  }
}
// component.ts
import { Component, VERSION } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  userName = new FormControl('test');

  constructor() {}

  submitForm() {
    console.log(this.userName.value);
  }
}
<!--component.html-->
<form novalidate (ngSubmit)="submitForm()">
  <div class="form-group row">
    <label for="UserName" class="col-2 col-form-label">User Name:</label>
    <div class="col-4">
      <input
        [formControl]="userName"
        class="form-control"
        id="UserName"
        name="userName"
        required
        appUpperCase
      />
      Model: {{ userName.value }}
    </div>
  </div>

  <button class="btn btn-primary" type="submit">Search</button>
</form>

I don't really understand why you're using HostListener (first of all, for keydown.backspace listener, you don't receive a value in the listener but the event).

Why not just listen to the valueChanges stream of the control, and update it there?

Also, you should use ReactiveFormsModule so you can get the value.

// directive.ts

import { Directive, OnDestroy, OnInit } from '@angular/core';
import { NgControl } from '@angular/forms';
import { Subject } from 'rxjs';
import { distinctUntilChanged, startWith, takeUntil } from 'rxjs/operators';

@Directive({
  selector: '[appUpperCase]',
})
export class UpperCaseDirective implements OnInit, OnDestroy {
  private _destroyed$ = new Subject<void>();

  constructor(private control: NgControl) {}

  processInput(value: any) {
    return value.toUpperCase();
  }

  ngOnDestroy(): void {
    this._destroyed$.next();
    this._destroyed$.complete();
  }

  ngOnInit(): void {
    this.control.valueChanges
      .pipe(
        startWith(this.control.value),
        distinctUntilChanged((first, second) => {
          return this.processInput(first) === this.processInput(second);
        }),
        takeUntil(this._destroyed$)
      )
      .subscribe((value) => {
        this.control.control.setValue(this.processInput(value));
      });
  }
}
// component.ts
import { Component, VERSION } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  userName = new FormControl('test');

  constructor() {}

  submitForm() {
    console.log(this.userName.value);
  }
}
<!--component.html-->
<form novalidate (ngSubmit)="submitForm()">
  <div class="form-group row">
    <label for="UserName" class="col-2 col-form-label">User Name:</label>
    <div class="col-4">
      <input
        [formControl]="userName"
        class="form-control"
        id="UserName"
        name="userName"
        required
        appUpperCase
      />
      Model: {{ userName.value }}
    </div>
  </div>

  <button class="btn btn-primary" type="submit">Search</button>
</form>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文