简体   繁体   中英

How to make the variables inside an imported component's function to reflect to their present values rather than their initial values in angular8?

I am declaring a private variable for the imported component in the constructor of the another component. Example

constructor( private x: Xcomponent){} 

Then i call a function declared inside Xcomponent

 x.scanx()

Inside the scanx function there is a variable whose initial value was ShouldChange=null; Before scanx was called its value was changed by another function inside Xcomponent as ShouldChange ={ 'some':'something'} ; Now when scanx is called from another component the value of ShouldChange is null. I have tried to access the values of variables declared and changed in class (Not component) and i get the present values not the initial ones as its happening when i try to access the values of imported components.

I am using visual code IDE. The language is typescript.

import { Xcomponent } from '../Xcomponent/xcomponent.component';
import { Globals } from '../globals';

export class parentComponent implements OnInit {
    constructor(private x: Xcomponent, private global: Globals) {
    }

    runThisFunction() {
        x.scanx(global.theVariableRetainsEditedValue); // The variable in global instance retains the changed values.
    }
}

// Inside scanx function of Xcomponent
export class Xcomponent implements OnInit {
    ShouldChange = null;

    someotherFunction() {
        this.ShouldChange = {'some': 'somethingelse'}
    }

    ngOnInit() {
this.someotherFunction();
this.confirmTheChange();
    }

    confirmTheChange() {
        if (this.ShouldChange === null) {
            alert("This never happens");
        }
        else {
            alert("THE VALUE WAS INDEED CHANGED");
        }
    }

    scanx(SomeInput) {
        if (this.ShouldChange === null) {
            alert("This Should not happen");
        } else {
            alert("This is not happening. Why?");
        }
    }
}

I expected the value of the variable ShouldChange to not be null since its changed in ngOninit. But it reflects its initial value when called from an imported instance of the component. However checking the variable's value from the unimported instance of the component shows that the value has indeed changed as shown in confirmTheChange() function.

The problem might be that you are not getting the new value because the function is not returning the new value ...

Well on the function that changed the y value, add a return y at the end as

scanx(){
*// the rest of the function that changed the code*
return y
}

and on the other component where you are calling 'scanx'

runThisFunction() {
 const y = x.scanx(global.theVariableRetainsEditedValue); // The variable in global instance retains the changed values.
*y will hold the new value*
}

If this not work, using observables would be a good solution. You create an observable in a service that will act as a data mediator between the two RxJS BehaviorSubject is a good option.

Step one - create a new service and create a BehaviorSubject and create a method for changing the value of the observable

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable()
export class ValueChangerService {
  private initialValue = new BehaviorSubject(0);
  currentValue = this.initialValue.asObservable();

  constructor() { }

  changeValue(value: number) {
    this.initialValue.next(value)
  }
}

Step Two inject the service to your components and change the value in one component

import { Component, OnInit } from '@angular/core';
import { ValueChangerService } from './value-changer.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  constructor(private valueChanger: ValueChangerService) {
  }


  setValue(value) {
    this.valueChanger.changeValue(value);
  }
}

Step Three Subscribe to it in the other component

import { Component, OnInit } from '@angular/core';
import { ValueChangerService } from "./value-changer.service";

@Component({
  selector: 'hello',
  template: `
   Hello Component
   the value of y is {{y}}
  `,
  styleUrls: ['./app.component.css']
})
export class HelloComponent implements OnInit {

  y: number;

  constructor(private valueChanger: ValueChangerService) { }
  ngOnInit() {
    this.valueChanger.currentValue.subscribe(value => this.y = value)
  }
}

you can find the full code at https://stackblitz.com/edit/angular-gvh6xj

And Check out https://angularfirebase.com/lessons/sharing-data-between-angular-components-four-methods/ by Jeff Delaney !

Working example

X Component

 import { Component, OnInit } from '@angular/core';
    import {TestService} from "./test.service"

    @Component( {
      selector: 'x-child',
      template: ``,
    })
    export class XchildComponent implements OnInit {

      constructor(private valueChanger: TestService) { 

         this.valueChanger.currentValue.subscribe(value =>  
         this.ShouldChange = value
            )
      }

      ShouldChange = null;

        someotherFunction() {
          //  this.ShouldChange = {'some': 'somethingelse'}

             this.valueChanger.changeValue({'some': 'somethingelse'});
        }

        ngOnInit() {

          this.someotherFunction();
          this.confirmTheChange();
        }

        confirmTheChange() {
            if (this.ShouldChange === null) {
                alert("This never happens");
            }
            else {
                alert("THE VALUE WAS INDEED CHANGED");
            }
        }

        scanx(value: any) {
            if (this.ShouldChange === null) {
                alert("This Should not happen");
            } else {
                alert("This is not happening. Why?");
            }
        }
    }

Parent component

import { XchildComponent } from './x-child.component'
import { Component , ViewChild, AfterViewInit} from "@angular/core";

@Component( {
  selector: 'parent',
  template: ``,

})
export class ParentComponent implements AfterViewInit {
constructor(public child: XchildComponent) {

}


ngAfterViewInit() {

this.child.scanx('checking new value')
}


}

Hope, this solves your problem

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM