从嵌套子组件内部访问父组件,而不在父组件中呈现子组件的HTML

时间:2017-02-24 17:22:09

标签: angular

我试图通过执行以下操作来访问我的父组件变量和方法,但收到错误消息:

error_handler.js:57 ORIGINAL EXCEPTION: Cannot read property 'getSelectedRow' of undefined

我试图通过以下方式来实现这一目标:

父组件:

get self(): SearchComponent{
        return this;
    }

尝试从子级访问的方法:

getSelectedRow():string {

        if(this.ssn != null){
            return this.ssn;
        }

        return "";

    }

家长的HTML:

<user-form [setUserSsn]="self"></user-form>

Childs组件:

@Component({
    selector: 'user-form',
    templateUrl: 'userForm.html',
    styleUrls: ['./userForm.css']

})
export class UserFormComponent {

    private _parentComponent: SearchComponent;

    @Input()
    setUserSsn(parent: SearchComponent){
        this._parentComponent = parent;
    }

    ssn = this._parentComponent.getSelectedRow();
}

-----------更新1 --------------------

我尝试了一种新方法,但现在我收到了错误:

Cannot read property 'getSsnFromSelectedRow' of undefined 
父组件中的

方法:

setClickedRow(user:User) {

        let ssn = user.ssn;

        this.setSsnForUsersForm(ssn);

        console.log("SSN: "+user.ssn);
    }

    setSsnForUsersForm(ssn:string){
        this.ssnForUsersForm = ssn;
    }

    getSsnFromSelectedRow():string{
        return this.ssnForUsersForm;
    }

调用子组件

ssn = this._parentComponent.getSsnFromSelectedRow();

------------------更新2 -------------------------- < / p>

我想我需要@Directive,但我认为我没有正确使用它。

子组件

@Component({
    selector: 'user-form',
    templateUrl: 'userForm.html',
    styleUrls: ['./userForm.css']

})
@Directive({selector: '[userSsn]'})
export class UserFormComponent {


}

parent.html

<tr saSmartMenu *ngFor='let data of user' (click)="setClickedRow(data)">
                    <td><a routerLink="/userManagement/maintainUsers/userForm">{{data.ssn}}</a></td>
                    <td><a routerLink="/userManagement/maintainUsers/userForm">{{data.userId}} </a></td>
                    <td><a routerLink="/userManagement/maintainUsers/userForm">{{data.lastName}}</a></td>
                    <td><a routerLink="/userManagement/maintainUsers/userForm">{{data.office}} </a></td>
                    <td><a routerLink="/userManagement/maintainUsers/userForm">{{data.role}} </a></td>
                    <span userSsn="data.ssn"></span>
                </tr>

现在,当用户选择一行时,子组件知道所选行的ssn。但它仍然无法正常工作。

--------------------更新3 ---------------

错误:

Can't bind to 'parent' since it isn't a known property of 'div'. ("
            </table>
        </div>
        <div userForm [ERROR ->][parent]="self"></div>
    </div>
</div

子组件

@Component({
    selector: 'user-form',
    templateUrl: 'userForm.html',
    styleUrls: ['./userForm.css']

})
@Directive({selector: '[userForm]'})
export class UserFormComponent implements OnInit  {

    @Input('parent') _parentComponent: SearchComponent;

    private ssn: string;

    ngOnInit() {
        this.ssn = this._parentComponent.getSsnFromSelectedRow();
    }

}

父html

<div userForm [parent]="self"></div>

2 个答案:

答案 0 :(得分:1)

@ tam5是对的。问题是您在分配之前尝试读取对象。

ssn = this._parentComponent.getSelectedRow(); // at this point your setUserSsn hasn't being called yet.

一种可能的方法是像这样实现ngOnInit,尽管有更好的方法https://angular.io/docs/ts/latest/cookbook/component-communication.html

import { OnInit } from '@angular/core';
// other imports here

export class UserFormComponent implements OnInit {

    private _parentComponent: SearchComponent;
    private ssn: string;

    @Input()
    setUserSsn(parent: SearchComponent){
        this._parentComponent = parent;
    }

    ngOnInit() {
       this.ssn = this._parentComponent.getSelectedRow();
    }
}

如果您不想在父级中呈现用户表单HTML,那么最合适的方法将是指令:

import { Directive, OnInit } from '@angular/core';
// other imports here

@Directive({
  selector: '[userForm]'
})
export class UserFormDirective implements OnInit {

  @Input('parent') _parentComponent: SearchComponent;

  private ssn: string;

  ngOnInit() {
    this.ssn = this._parentComponent.getSelectedRow();
  }
}

然后你可以像这样使用它: <div userForm [parent]="self"></div>

答案 1 :(得分:0)

您可以通过@input()传递selectedRow,我认为发送孔组件对于性能不是很好。

类似的东西:

家长的HTML:

<user-form [ssn]="ssn"></user-form>

Childs组件:

@Component({
    selector: 'user-form',
    templateUrl: 'userForm.html',
    styleUrls: ['./userForm.css']

})
export class UserFormComponent {
    // starts as an empty string to avoid missing parameters issues
    @Input() ssn: string = ''; 

}