Angular 2共享服务变量返回undefined

时间:2017-01-23 19:04:56

标签: angular

我正在尝试从navMenu.component设置并由tab.component使用的共享服务中获取值。我觉得它是正确共享的,但是当tab.component获取值时为时已晚。我试图使用Elvis操作符但是出现了错误。

启动app.component.html

<div>
    <div class="outer">

            <nav-menu [gwLinkID]="gwLinkID"  [psnlUID]="psnlUID"  [ntName]="ntName"></nav-menu>


        </div>

        <div class="main">
            <div class="container">  
               <tab></tab>
            </div>
</div>

共享服务的值由navMenu.component

设置
@Component({
    selector: 'nav-menu',
    moduleId: module.id,
    templateUrl: 'navMenu.component.html'
})

export class NavMenuComponent implements OnInit {

    tabs: INavMenuTabs[];

    @Input() gwLinkID: number;
    @Input() psnlUID: string;
    @Input() ntName: string;
    pageTitle: any[];
    title: string;
    titleID: number;
    appParams: IAppParams;
    errorMessage: string;
    linkData: any;
    constructor(private _appParams: AppParamasService, private _navMenuService: NavMenuService) {
//    this.gwLinkID = this._appParams.LinkID;
    console.log('inside navMenu.component constructor ' + this._appParams.GetLinkName);


}

getTabs() {
    this._navMenuService.getTabs(this._appParams.LinkID, 'ciiw')
        .subscribe(
        data => {
            this.tabs = data.result
        },
        error => this.errorMessage = <any>error),
        this.appParams = this._appParams.GetParams();
    console.log('inside navMenu.component method getTabs ' + this._appParams.GetLinkName);
}
ngOnInit(): void {

    this._navMenuService.getLinkName(this.gwLinkID)
        .subscribe(
        data => {
            this.titleID = data.result.LinkID;
            this._appParams.SetLinkID = data.result.LinkID;
            this.title = data.result.LinkName;
            this._appParams.SetLinkName = this.title;
            this._appParams.SetParams(this.psnlUID, this.ntName, this.gwLinkID);
            this.getTabs(); // call the tabs-method here, data is available here!
        });
    console.log('inside navMenu.component method ngOnInit ' + this._appParams.GetLinkName);
    }

}

共享服务

@Injectable()

export class AppParamasService {

    params: IAppParams;
    constructor() {

    }

    private _linkName: string;
    get GetLinkName(): string {
        return this._linkName;
    }
    set SetLinkName(value: string) {
        this._linkName = value;
    }


}
tab.component

使用

共享服务方法

@Component({
    selector: 'tab',
    moduleId: module.id,
    templateUrl: 'tab.component.html'
})
export class TabComponent implements OnInit {

    linkName: string;
    appParams: IAppParams;
   constructor(private _appParams: AppParamasService) {

    console.log('inside tab.component constructor ' + this._appParams.GetLinkName);

}

CheckValue()
{
   console.log('inside tab.component CheckValue ' + this._appParams.GetLinkName);
}
ngOnInit(): void {

    this.linkName = this._appParams.GetLinkName;
    console.log('inside tab.component ngOnInt ' + this._appParams.GetLinkName);


}
}

tab.component.html

<div class="team">
       <h3 *ngIf="linkName">{{linkName}}</h3>
</div>

如果我将navMenu.component.ts中的构造函数更改为

,则需要注意一件事
  

构造函数(private _appParams:AppParamasService,private   _navMenuService:NavMenuService){

    this._appParams.SetLinkName = 'Test';

}

一切正常,而且值可用于tab.component.ts,所以这是一个问题,在哪个阶段值可用于其他共产主义

从控制台日志输出

  • 在navMenu.component构造函数undefined
  • inside tab.component构造函数undefined
  • 内部navMenu.component方法ngOnInit undefined
  • inside tab.component ngOnInt undefined
  • 内部navMenu.component方法getTabs财务计划报告 管理员

2 个答案:

答案 0 :(得分:2)

由于nav componenttab component同时初始化,这意味着当执行OnInit中的tab component时,共享服务中的值尚未得到一个值发送到tab component。这可以解决,以使共享服务使用Subjects,以便选项卡组件将订阅该值。

所以你的服务应该是这样的:

private linkNameSource = new Subject<any>();
linkNameValue$ = this.linkNameSource.asObservable();

  linkNameReceived(linkName) {
    //emit linkName, your tab component will subscribe to this value in constructor
    this.linkNameSource.next(linkName)
  }

并在nav component中更改此内容:

this._appParams.SetLinkName = this.title;

到以下(我们将值推送到您的共享服务),这将向您的tab component发出值,订阅该值。

this._appParams.linkNameReceived(this.title)

然后在标签组件中添加以下内容:

// declare your local variable
linkName;

constructor(private _appParams: AppParamasService) {
  // subscribe to the value from the shared service
  this._appParams.linkNameValue.subscribe(linkName => {
    this.linkName = linkName;
  }
}

这应该清楚了!请参阅angular.io中的link,其中我为您提供的相同示例的解释比我提供的更多详细信息。

答案 1 :(得分:0)

如果没有像

这样的后续表达式,则不能使用可选运算符
 {{foo?.bar}}

其目的是在父级为undefinednull时阻止对属性的访问冲突。在你的例子中,你只有一个简单的对象,可以打印,例如为nullundefined

如果链接未定义,也许您希望不呈现完整的h3。像这样的东西

 <h3 *ngIf="linkName">{{linkName}}</h3>