【问题标题】:Pass value from input component to button component in Angular application将值从输入组件传递到 Angular 应用程序中的按钮组件
【发布时间】:2021-06-30 23:00:06
【问题描述】:

我试图弄清楚如何将值从一个 Angular 组件传递到另一个 my-input.componentmy-button.component

我正在尝试从my-input.component.ts 接收并在my-button.component.ts 中使用来自my-button.component.html 的按钮(click)="displayReceivedValue()" 显示@Input('name')

import { Component, Input, OnInit } from '@angular/core';
import { MyInput } from '../../interfaces/my-input';

@Component({
  selector: 'app-my-button',
  templateUrl: './my-button.component.html',
  styleUrls: ['./my-button.component.scss'],
})
export class MyButtonComponent implements OnInit {
  @Input('name')
  public input!: MyInput;
  constructor() {}

  ngOnInit(): void {}

  async displayReceivedValue() {
    console.log('Received value: ', this.input);
  }
}

这是Login page 中的<app-my-button name=""></app-my-button> 组件my-input.component.ts 中的this.myValuethis.myValue 中的input 中的my-input.component.html,但我不确定如何将它传递给@ 987654337@:

import { Component, EventEmitter, OnInit, Output } from '@angular/core';

@Component({
  selector: 'app-my-input',
  templateUrl: './my-input.component.html',
  styleUrls: ['./my-input.component.scss'],
})
export class MyInputComponent implements OnInit {
  
  public myValue: any;

  constructor() {}

  ngOnInit(): void {}
}

我还尝试在来自my-input.component.tsLogin page 中使用@Output()<app-my-button (inputValue)="acceptData($event)"></app-my-button> 组件:

import { Component, EventEmitter, OnInit, Output } from '@angular/core';
    
    @Component({
      selector: 'app-my-input',
      templateUrl: './my-input.component.html',
      styleUrls: ['./my-input.component.scss'],
    })
    export class MyInputComponent implements OnInit {
      @Output() inputValue= new EventEmitter<string>();
        
      public myValue: any;

      constructor() {}
    
      ngOnInit(): void {
           this.inputValue.emit(this.inputValue);
      }
    }

my-button.component.ts:

import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'app-my-button',
  templateUrl: './my-button.component.html',
  styleUrls: ['./my-button.component.scss'],
})
export class MyButtonComponent implements OnInit {
  constructor() {}
  ngOnInit(): void {}
  acceptData(data: any) {
    console.log(data);
  }
}

如果我将(inputValue)="acceptData($event) 添加到my-button.component.html,或者如果我将(inputValue)="acceptData($event) 添加到login.component.html 我得到错误:

TS2339:类型上不存在属性“acceptData” '登录组件'。

【问题讨论】:

    标签: angular typescript angular-cli angular-components


    【解决方案1】:

    选项 1:使用 ControlValueAccessor

    尽量简单;假设您的应用组件中有以下内容

    app.component.html

    <app-my-input [(ngModel)]='myValue'></app-my-input>
    <app-my-button [name]='myValue'></app-my-button>
    

    app.component.ts

     myValue = 'MyValue'
    

    基本上我们绑定到app.component.ts 中的相同值。所以值会在更改时更新为按钮name属性。

    现在如果你尝试在上面运行,你会收到一个错误

    没有名称为app-my-input的控件的值访问器

    那是因为我们绑定到需要实现ControlValueAccessorngModel。所以我们像下面这样实现这个

    my-input.component.ts

    @Component({
      selector: 'app-my-input',
      templateUrl: './my-input.component.html',
      styleUrls: ['./my-input.component.css'],
        providers: [
        {
          provide: NG_VALUE_ACCESSOR,
          useExisting: forwardRef(() => MyInputComponent),
          multi: true
        },
        ]
    })
    export class MyInputComponent implements ControlValueAccessor {
      
      myValue = '';
      constructor() { }
      writeValue(value: any): void {
        if (value !== undefined) {
          this.myValue = value;
        }
      }
      onChanges: ($value: any) => void;
      onTouched: () => void;
    
      registerOnChange(fn: any): void {
        this.onChanges = fn;
      }
    
      registerOnTouched(fn: any): void {
        this.onTouched = fn;
      }
    }
    

    my-input.component.ts

    <input [(ngModel)]='myValue' (ngModelChange)='onChanges(myValue)'>
    

    现在我们的app-my-input 就像普通输入一样工作,我们可以绑定到[(ngModel)] 指令

    所以现在在我们的app-my-button 中,我们可以使用@Input 装饰器接收这个

    app-my-button.ts

      @Input() name = "";
      constructor() {}
    
      ngOnInit(): void {}
    
      displayReceivedValue() {
        console.log("Received value: ", this.name);
      }
    

    app-my-button.html

    <button (click)='displayReceivedValue()'>My button</button>
    

    现在,如果您单击按钮,您将在控制台中看到带有输入值的日志

    Demo Here

    选项 2:使用 @Output@input 装饰器

    要使用@input@Output,您只需定义您输入的内容类似于

    export class MyInputComponent implements OnInit {
      
      @Input() input = '';
      @Output() output: EventEmitter<string> = new EventEmitter()
      myValue = '';
      constructor() { }
      onChanges = ($event) => {
        this.output.emit($event)
      }
    
      ngOnInit() {
        this.myValue = this.input
      }
    }
    

    在html中

    <input [(ngModel)]='myValue' (ngModelChange)='onChanges(myValue)'>
    

    现在我们绑定到(ngModelChange)。当值改变时,我们使用定义为EventEmitter&lt;string&gt;output 属性发出值

    然后我们可以收到这个

    <app-my-input [input]='myValue' (output)="myValue = $event"></app-my-input>
    

    See this Demo

    【讨论】:

    • 您好!这么晚才回复很抱歉。所以我必须在 '[(ngModel)]="myValue" ( 'my-input.component.html' 中的 ngModelChange)="onChanges(myValue)"',提供的代码给出了所需的结果,我将被标记为答案,但由于我是 Angular 的新手,我仍在尝试弄清楚,如何在同一个任务中使用“输出”和“输入”。我正在查看 Angular 文档 angular.io/guide/inputs-outputs,但看起来我遗漏了一些东西,因为该值始终未定义
    • 在更新的解决方案中查看我上面的方法
    猜你喜欢
    • 1970-01-01
    • 2021-09-20
    • 2018-12-24
    • 1970-01-01
    • 2020-03-24
    • 1970-01-01
    • 2021-04-21
    • 2018-04-16
    • 1970-01-01
    相关资源
    最近更新 更多