通过订阅方法将数据传递到组件

时间:2019-02-10 20:51:15

标签: angular

我试图通过订阅将数据从新产品组件(父组件)传递到新卡片组件(子组件),但是当我尝试通过单击保存按钮来控制台记录数据时,我什么都没看到……第二次我单击“保存”按钮,然后数据显示在控制台日志中

Newproducts.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';
import { Productservice } from 'src/app/services/products.service';

@Component({
  selector: 'app-new-products',
  templateUrl: './new-products.component.html',
  styleUrls: ['./new-products.component.scss']
})
export class NewProductsComponent implements OnInit {
  default = "Bread";
  values;
  @ViewChild('f') form: NgForm;
  constructor(private router: Router,
              private route: ActivatedRoute,
              private prservice: Productservice) { }

  ngOnInit() {

  }

  onsubmit() {
    this.values = this.form.value;
    this.prservice.productcard.next(this.values);
    // console.log(this.form.value)
    // console.log(this.values)
    this.router.navigate(['card'], { relativeTo: this.route })
  }
}

Newcard.component.ts

import { Component, OnInit } from '@angular/core';
import { Productservice } from 'src/app/services/products.service';
import { Router, ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-new-card',
  templateUrl: './new-card.component.html',
  styleUrls: ['./new-card.component.scss']
})
export class NewCardComponent implements OnInit {
  subscription: Subscription;

  constructor(private prservice: Productservice,
              router: Router,
              route: ActivatedRoute) { }

  ngOnInit() {
    this.subscription = this.prservice.productcard.subscribe(
      (value) => {
        const cardvalue = value;
        console.log(cardvalue);
      }
    )
  }
}

Products.service.ts

import { Subject } from "rxjs";

export class Productservice {
   productcard = new Subject<[]>();
} 

3 个答案:

答案 0 :(得分:2)

在发布此代码之前,请使用更好的代码格式。

很难解决该代码。无论如何,如果您的card路线激活了子组件。然后的问题是,在创建子组件之前,您将新值传递给主题。而且由于该子组件不知道“主题”更改,因为订阅后并未发生。

常规Subject的工作原理如下。您必须先更改主题,然后再进行订阅,否则它将没有任何价值!

您应该使用BehaviorSubject。此处的区别在于BehaviorSubject始终拥有一个值。当有人订阅时。它将发出它持有的最后一个值。

希望我回答了你的问题。

答案 1 :(得分:1)

您无需使用此Productservice,您所需要做的就是使用function checkKanga(kangaArr) { if (kangaArr[0][0] > kangaArr[1][0]) return 'NO'; if (kangaArr[0][0] === kangaArr[1][0]) return 'YES'; kangaArr[0][0] += kangaArr[0][1]; kangaArr[1][0] += kangaArr[1][1]; checkKanga(kangaArr); } checkKanga([ [ 0, 3 ], [ 4, 2 ] ]); 绑定将值传递给子组件。

在文档Pass data from parent to child with input binding

中了解有关此内容的更多信息

然后,您必须在子组件中实现@Input()接口,并且每次用@Input()装饰的属性的值更改时,都会调用NgOnChange方法。

答案 2 :(得分:0)

@Ales答案很可能是正确的,假设您的子组件是在共享服务通过父组件对其主题发出新值之前创建的,那么您可能会遇到依赖实例错误。

如果您使用此语法,则在提供服务时就会创建您的服务,那么该服务将确保它是单例(我认为)。

@Injectable({
  providedIn: UserModule,
})

但是,在模块级别使用此语法,可能有多个服务实例处于活动状态,而不同的组件使用了不同的主题来订阅

@NgModule({
  providers: [UserService],
})