Angular 2, Cant able to access a variable in one Component from another Component

我的未来我决定 提交于 2020-01-03 17:25:30

问题


Sorry if this is a duplicated question, I have searched solution throughout the Web can't able to find any so am posting it, Am trying to access a variable from one component inside another component

What I have Tried

I have created a model of object type and have set the value inside a component A method, and tried to access that model object from component B so that I can set the value for the Component B Elements, but getting object as undefined

Problem

Component A is loaded first in browser, where it contains a table on click of the table row am getting the row data as object and setting that object to a Model which contains a similar structure object and I can able to get the object value in Component, whereas I tried to call the model from a Component B so that I can access the object value. but am getting the object value as undefined this is due to the Component B is a Modal which is Called inside the Component A Template.

Component A

 public rowSelected:boolean = true;
 constructor(public users : User ) {}
  getRowData(rowIndex: number, rowData: any): void { 
        this.rowSelected = $(rowIndex).hasClass('selected');
        console.log(rowData);
        this.users= rowData.FirstName;
        console.log(this.users); // can able to get the object value
    }

Component A Template

<div bsModal #editUserModal="bs-modal" class="modal fade" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <button class="close" aria-label="Close" type="button" (click)="editUserModal.hide()">
                    <span aria-hidden="true">&times;</span>
                </button>
                <h5 class="modal-title"><b>Edit User</b></h5>
            </div>
            <div class="modal-body">
                <componenetB #edituserDiv></componenetB>
            </div>
            <div class="modal-footer">
                <button class="btn btn-primary btn-sm  confirm-btn gap0" type="button" (click)="edituserDiv.EditUserSubmit()">Submit</button>
                <button type="button" class="btn btn-default btn-sm gap-left10 gap0" type="button" (click)="editUserModal.hide()">Close</button>
            </div>
        </div>
    </div>
</div>

Model

export class User {
    UserName: any
    Password: any
    FirstName: any
    MiddleName: any
    LastName: any
    Status: any
    Locked: any
    Active: any
    CreatedOn: any
    LastModified: any

}

Component B

export class Component B   { 

    constructor(public userz : User) {     
console.log(this.userz) // Object Value is Undefined
    }

}

Please help me to resolve this issue, thanks in advance


回答1:


Use @Input when you want to pass data from parent to child. Here I assume users is an array. If not, adjust the type accordingly.

So in your parent template:

<componenetB [users]="users"></componenetB>

From your child (component B), do not inject User in constructor. Use @Input instead:

export class Component B   { 
    @Input users: User[];

    constructor() { }
}

So that you do not get undefined error if the users is actually set later, just instantiate the users in your parent, so that it won't be undefined, while it waits for values to be set:

users: User[] = [];

Here is a demo, which simulates the values of users are set at a later point. Just click the button and the values will appear in child, values that are set in the parent.

Plunker




回答2:


I can't see the binding. May be you are missing something like <hero-detail [hero]="selectedHero"></hero-detail>




回答3:


Component A

import {Component,EventEmitter} from "@angular/core";
import {User} from "User.Model";

@Component({
   selector: 'component-A',
   outputs :["selectedUser"],
   templateUrl:''
})

export class AppComponent{
 selectedUser : new EventEmitter<User>;
 public rowSelected:boolean = true;
 constructor(public users : User ) {}
 getRowData(rowIndex: number, rowData: any): void { 
        this.rowSelected = $(rowIndex).hasClass('selected');
        console.log(rowData);
        this.users= rowData.FirstName;
        this.selectedUser.emit(this.users);
    }
}

Component B Html

<component-a (selectedUser)="PrintUserInfo($event)"></component-a>

Component B.ts

// skipping some code
export class BComponent{
     PrintUserInfo(user :User): void {
       console.log("Name :" + user.Name);
   }
}



回答4:


I hope I understand your question. If this answers you question remember to mark it as answer.

If you have a component (A - parent) which has child component (B - child), then you can use Input/Output decorators to communicate between them.

Child component has event property userSelected, it will fire event when emit(value?: T): void method will be called. Parent component will receive event here - (userSelected)="onUserSelect($event) where $event contains value passed to emit method. So it can be used in parent component

More detailed description here: http://learnangular2.com/outputs/

Parent:

@Component({
   selector: 'component-a',
   template:'<component-b (userSelected)="onUserSelect($event)"></component-b>'
})
export class AComponent{
    selectedUser: User;
    onUserSelect(user: User){
       this.selectedUser = user;
    }
}

Child:

@Component({
   selector: 'component-b'
})
export class BComponent {
   @Output() userSelected: EventEmitter<User>;

   rowClicked(user: User): void {
       this.userSelected.emit(user);
   }
}

UPDATE - Input version

According to Component A template, component B is child of component A

Further I go into your implementation, I get the feeling that whole logic is weird. As I understand, you have a table of users in Component A, then when a row is selected modal window pops up (component B) where you manipulate user details. So template for component A should look like this (simplified version):

<div class="modal-body">
   <componenetB [selectedUser]="selectedUser"></componenetB>
</div>

Then for B component define input variable with same name as used in A template

@Component({
   selector: 'component-b'
})
export class BComponent {
   @Input() selectedUser: User;

   //Further your logic using selectedUser variable
   //If need to return modified selectedUser to A component, use Output
}

Well it seems that you miss code logic to select user. I guess you should have something similar to this, that is just an example. You should pass whole object to component B.

<table>
   <tr*ngFor="let user of users">
      <td (onClick)="openBModal(user)">{{user.UserName}}</td>
   </tr>
</table>

To give more precise answer please provide plunker with your example, with this little information is hard to understand what are you going to achieve



来源:https://stackoverflow.com/questions/43347526/angular-2-cant-able-to-access-a-variable-in-one-component-from-another-componen

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!