【问题标题】:Passing Values between two components in Angular在 Angular 中的两个组件之间传递值
【发布时间】:2021-08-23 05:25:31
【问题描述】:

我正在尝试将值从一个组件传递到其他组件,到目前为止,我已经参考了一些 tuts 并创建了我的代码,但仍然面临问题。

我的 SelectComponent.ts 中有以下代码

    export class SelectComponent implements OnInit {
 user: LoginUser
 selectLicences = [
  { name: 'Control', id: 1, isChecked: false, quantity: 1 },
  { name: 'Complete', id: 2, isChecked: false, quantity: 1 },
 ]

ControlQuantity=10
CompleteQuantity=20

我想在我的其他“buyerComponent”中访问 ControlQuantity 和 CompleteQuanitiy

这里是buyerComponent.ts

    export class BuyerComponent implements OnInit, OnDestroy,AfterViewInit {​
@ViewChild('selectProducts', {​ read: SelectComponent, static: false }​)
selectProducts: SelectComponent

CompleteQuantity:number
ControlQuantity:number
ngOnInit() {
    this.CompleteQuantity=this.selectProducts.CompleteQuantity
    this.ControlQuantity=this.selectProducts.ControlQuantitity
}
}

stackblitz 链接:https://stackblitz.com/edit/angular-ivy-umje3g?

【问题讨论】:

  • selectProducts是什么,组件之间有什么关系?请参考this video你会明白的
  • 我添加了完整的 BuyerComponent
  • 请也添加 HTML。
  • 尝试在您的子组件上使用@Input。尽量避免使用@ViewChild。它不适合单元测试
  • 不要让你的一个组件侵入和访问另一个组件的内部事务。如果没有服务,更好的方法是拥有一个充当中介的父组件。组件 A 发出一个事件,该事件被监听并传递给组件 B。@Input 和 @output 是你的朋友。 angular.io/guide/inputs-outputs

标签: angular typescript


【解决方案1】:

可以参考官方文档。 https://angular.io/guide/inputs-outputs#sending-data-to-a-child-component

您可以通过 @Input() 装饰器将数据传递给您的子组件。

export class buyerComponent implements OnInit{
    @Input() CompleteQuantity:number
    @Input() ControlQuantity:number
    
    ngOnInit() {
        this.CompleteQuantity=this.selectProducts.CompleteQuantity
        this.ControlQuantity=this.selectProducts.ControlQuantitity
    }
}

在您的 HTML 页面中,您可以通过子组件的选择器标签传递数据。

更新:看到代码后。

  • 在 AppModule 中,从 Import 中移除 BuyerComponent 和 Products 组件并将它们添加到声明数组中。

  • Buyer.component.html 中的标签不正确。正确的标签是 “app-products”而不是“app-select-products”。

  • 将这些添加为产品组件类中的@Input()

         @Input() CompleteQuantity:number
         @Input() ControlQuantity:number
    
  • 将现有的 Output() 变量重命名为 products.component.ts 类中的另一个名称。

【讨论】:

  • core.js.pre-build-optimizer.js:4002 错误错误:未捕获(承诺中):TypeError:无法读取未定义的属性“ControlQuantity” TypeError:无法读取未定义的属性“ControlQuantity”在 e. (buyer.component.ts:1418) at tslib.es6.js.pre-build-optimizer.js:100
  • @sonu2007 是否可以共享代码仓库。您的代码中似乎有些地方不对劲。 Github 或 Stackbliz 都很棒。
  • 这里是 stackblitz.com/edit/angular-ivy-umje3g?
  • @sonu2007 代码中有很多地方不正确。我已经基于此更新了我的答案。
  • 现在工作.. 谢谢
【解决方案2】:

你有两种选择:

  1. 您可以使用单例服务:
@Injectable({providedIn: 'root'})
export class SharedService {
  sharedValue = 1
}
@Component({…})
export class Component1 implements OnInit {
  public get prop(): number {
    return this.service.sharedValue;
  }
  constructor(private service: SharedService) { }
}
@Component({…})
export class Component2 implements OnInit {
  public get prop(): number {
    return this.service.sharedValue;
  }
  constructor(private service: SharedService) { }
}
  1. 您必须将父组件用作数据桥

父级(桥组件)

请注意,父级并没有做很多事情,而是在子级之间提供共享数据之间的绑定。

<div>
  <app-child1 
    [value]="value"
    (valueUpdated)="onChangeValueFromChildren($event)">
  </app-child1>
  <app-child2 
    [value]="value"
    (valueUpdated)="onChangeValueFromChildren($event)">
  </app-child2>
</div>
@Component({…})
export class ParentComponent implements OnInit {

  value = 2
  
  onChangeValueFromChildren(newValue: number) { 
    this.value = newValue
  }
}

任何子组件

@Component({…})
export class Child1 implements OnInit {

  @Output valueUpdated = new EventEmitter<number>();
  
  onClick() { 
     this.valueUpdated.next(Math.random())
  }
}

【讨论】:

  • 我在工作中使用的是服务方式,目前运行良好,操作起来并不麻烦
  • @some-random-IT-boy :谢谢,但不是专业人士刚开始使用它,所以不确定在哪里添加“@Injectable......”
  • 您应该使用angular-cli 来生成您的服务,方法是:ng generate service {the service name here}
  • 如果您指的是向“服务”添加代码,而不是我要求不使用“服务”的情况
  • 我找不到您声明您不想使用服务的地方。无论如何,您在我的回答中有两种选择:第一种是使用服务(它会做@Injectable 的事情;如果您不想要它,请随意跳过它!)。您剩下的是“使用父组件”作为数据桥方法
猜你喜欢
  • 2016-04-29
  • 2020-10-10
  • 2018-02-22
  • 1970-01-01
  • 2016-07-20
  • 2021-04-13
  • 2017-01-12
  • 2016-05-09
相关资源
最近更新 更多