【问题标题】:How to detect changes from child directive in Angular 6如何检测Angular 6中子指令的变化
【发布时间】:2019-07-14 18:23:08
【问题描述】:

我尝试创建看起来像搜索表单的自定义组件。我用选择器my-search 创建了SearchComponent,在其中我放置了带有附加指令InputDirective 和选择器[myInput] 的HTML <input> 元素:

<my-search>
  <input myInput>
</my-search>

问题是如何检测来自InputDirective 内部SearchComponent 的变化?例如:当用户在输入中输入一些文本时,我应该启用或禁用按钮:

search.component.html

<ng-content select="[myInput]"></ng-content>
<button type="button" [disabled]="!searchText">Search</button>

我尝试订阅组件内部指令的更改,但它不起作用。

search.component.ts

@Component({
  selector: 'my-search',
  templateUrl: './search.component.html'
})
export class SearchComponent implements AfterContentInit {
  @ContentChild(InputDirective) input: InputDirective;

  ngAfterContentInit() {
    this.input.changes.subscribe(changes => console.log(changes));
  }
}

我还尝试在属性element 中导出本机输入。

input.directive.ts

@Directive({
  selector: '[myInput]'
})
export class InputDirective {
  element: HTMLInputElement;

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

当尝试使用 getter 获取输入值时,它也不起作用。

search.component.ts

@Component({
  selector: 'my-search',
  templateUrl: './search.component.html'
})
export class SearchComponent implements AfterContentInit {
  @ContentChild(InputDirective) input: InputDirective;

  get searchText(): string {
    return this.input.element.value;
  }
}

谁能帮我解决这个问题?这里是link 用于实验。

【问题讨论】:

  • 简单的二传手适合你吗?
  • 我添加了这个设置器,但它没有任何改变。 set searchText(value: string) { this.input.element.value = value; }

标签: angular angular6 angular2-directives angular2-components


【解决方案1】:

在 Angular(版本 2+)中,我们有一个叫做 EventEmitter 的东西 使用哪个子组件可以发出任何更改

    Below is what you need in your child component
     1)@Output() change: EventEmitter<string> = new EventEmitter<string>();

    2)Also add a method that emits change when keypress event occurs
        onKeyPress(value: string) {
                this.change.emit(value);
            }
    3)change your html
    <my-search>
      <input myInput (change)="searchChange($event)">
    </my-search>

     4)change your boolean "searchText" in the method searchChange as below
       public searchChange(event:any)
{
if(event && event.length>0)
searchText=true
}

【讨论】:

    【解决方案2】:

    看起来您实际上并没有深入到您要监控的输入元素,请尝试:

    @Component({
      selector: 'my-search',
      templateUrl: './search.component.html'
    })
    export class SearchComponent implements AfterContentInit {
      @ContentChild(InputDirective) input: InputDirective;
    
      ngAfterContentInit() {
        this.input.element.addEventListener('change', e => console.log(this.input.element.value));
      }
    }
    

    这就是你要找的吗?

    【讨论】:

    • 感谢您的回答。是的,这是可行的,但它看起来不是 Angular 的方式。
    【解决方案3】:

    您正在寻找的是指令中的 HostListener :

      @HostListener('keypress') changed;
    

    您可以深入了解它以及哪些事件可用,但每次按下搜索按钮时都会触发更改,您有其他类似 'keydown' 但您应该尝试一下

    如果你想看看https://www.w3schools.com/tags/ref_eventattributes.asp,这里有更多活动列表

    编辑:您甚至可以通过向更改方法主体添加更多内容以触发输出事件返回父组件以继续处理该事件,但对于我从您的问题中了解到的主机监听器会做的事情。

    【讨论】:

    • 如果您希望仅在单击“搜索”时显示搜索文本,请使用“更改”事件
    • 如何在组件中使用这个事件发射器?
    猜你喜欢
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    • 2019-11-09
    • 2016-03-01
    • 1970-01-01
    • 2017-09-01
    • 2017-02-15
    相关资源
    最近更新 更多