订阅(rxjs)中的初始化变量始终未定义Angular 6

时间:2019-04-11 14:03:29

标签: rxjs angular6

我已经使用Angular 6工作了几个月。我有两个组成部分: 第一个(父)必须通过http请求读取参数并初始化内部属性;第二个(子代)在其自己的属性上使用@Input装饰器获取此参数。我无法在订阅方法中设置父属性,该属性未定义。 有什么建议吗?

父组件:

// components/LogIn
import React, { useEffect, useState } from 'react';
import { setUser, getUser } from 'components/User/actions';

function click() {
  setUser({
    name: 'John',
    phone: '32323232',
  });
}

function useCurrentUser() {
  const [currentUser, setCurrentUser] = useState(null);

  useEffect(() => {
    setCurrentUser(getUser());
  }, []);

  return currentUser;
}

function Login() {
  const currentUser = useCurrentUser();

  return (
    <div>
      {currentUser && (
        <div>
          <h2>User info</h2>
          <ul>
            <li>Name: {currentUser.name}</li>
            <li>CPF: {currentUser.cpf}</li>
            <li>Phone: {currentUser.phone}</li>
          </ul>
        </div>
      )}

      <button type="button" onClick={click}>
        Set User state
      </button>
    </div>
  );
}

export default Login;

子组件:

export class DeliberaComponent implements OnInit {

  private categoria: string = 'delibera';
  private prefix: string;

  constructor(private sistemaService: SistemaService) {
    this.sistemaService.readCategoriaAttributes(this.categoria)
    .subscribe(categoria => {
      this.prefix = categoria.listCategoriaAttribute.filter(attr => attr.chiave === 'prefixNamePdv').pop().valore; 
    });
  }

  ngOnInit() {
  }
}

这是html片段:

export class CreazioneManualeComponent implements OnInit {

  @Input()
  private prefix: string;
  private idpdv: string;

  ngOnInit() {
    this.idpdv = 
    this.prefix.concat(newDate().toDateString());
  }
}

2 个答案:

答案 0 :(得分:0)

如果您通过http获取信息,则在创建子组件之前将无法获得任何响应,因此,当ngOnInit运行时,将没有前缀。

您可以这样做。...

    ngOnChanges(change: SimpleChanges) {
        If (change.prefix) {
            this.idpdv = 
            this.prefix.concat(newDate().toDateString());
        }
    } 

但这是相当昂贵的,因为它将检查每次changeDetection是否在子组件上每次运行。...如果可以更好的选择是直接在父组件的订阅中直接将日期添加到字符串中。您还可以创建一个纯管道,如果您在子组件的html中使用它,它将为您完成此任务。

答案 1 :(得分:0)

在@Tzannetos Philippakos解释之后,我找到了可行的解决方案:

export class DeliberaComponent implements OnInit {

  private categoria: string = 'delibera';
  private prefix: string;
  @ViewChild(CreazioneManualeComponent)
  private childCreazioneManuale: CreazioneManualeComponent;

  constructor(private sistemaService: SistemaService) {
  }
  
  ngOnInit() {
  }
  
  ngAfterViewInit () {
    this.sistemaService.readCategoriaAttributes(this.categoria)
    .subscribe(categoria => {
      let prefix = categoria.listCategoriaAttribute.filter(attr => attr.chiave === 'prefixNamePdv').pop().valore;
      this.childCreazioneManuale.setPrefix(prefix); 
    });
  }
}

在子组件中:

 setPrefix(prefix: string){
    this.idpdv = prefix.concat(new Date().toDateString());
    this.headerForm.controls['idpdv'].setValue(this.idpdv)
  }

HTML:

<sa-creazione-manuale [categoria]="categoria" ></sa-creazione-manuale>