【问题标题】:Angular 2 shared service variables return undefinedAngular 2 共享服务变量返回未定义
【发布时间】:2017-06-08 09:37:15
【问题描述】:

我正在尝试从由 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 中的构造函数更改为

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

    this._appParams.SetLinkName = 'Test';

}

一切正常,并且该值可用于 tab.component.ts,因此在哪个阶段值可用于其他组件是一个问题

控制台日志的输出

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

【问题讨论】:

标签: angular


【解决方案1】:

由于nav componenttab component是同时初始化的,这意味着当tab component中的OnInit被执行时,来自共享服务的值还没有得到一个值发射到@ 987654326@。这可以通过使共享服务使用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,其中我为您提供的同一个示例的解释比我提供的更多。

【讨论】:

  • 感谢 AJT,抱歉错字是 LinkName 而不是 LinkNam。我更新了上面的代码。问题仍然存在。我什至把它放在一个名为 title 的变量中并显示在 navMeu.htlm 中只是为了查看它,并且值显示出来了,所以这一行 this._appParams.SetLikName = data.result.LinkNam;工作中 。检索该值以供另一个控件使用时,该值不是持久的。
  • 好吧,你的帖子里有这么多代码,所以很难理解,至少对我来说,我在阅读所有代码时遇到了困难:D 甚至不知道在哪个order nav 组件和 tab 组件被执行。它们是同时加载的吗?某处是否有导航,或者应用程序是如何构建的?
  • 您是否一直在控制台登录,数据究竟在什么时候仍然完好无损,究竟在哪里丢失了?
  • 通过删除不相关的代码来编辑我的代码。是的,所有代码都是同时加载的。请参阅 app.compoenet.html。问题在于 。我可以将它的标题作为输入传递,但我真的不想这样做。上面的代码更清晰吗?是的,我在 navMenu.component.ts 中设置了 consol 日志,并且能够确认该值已设置。在它打印未定义的 tab.component 中也做了同样的事情
  • 太棒了!不客气。花了一些时间,但你终于找到了解决方案:D
【解决方案2】:

如果没有像

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

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

如果链接未定义,您可能希望不呈现完整的h3。像这样的

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

【讨论】:

  • 我试过了,但我没有得到价值,这不能解决我的问题。那么为什么我的 linkName 是未定义的?它被 navMenu.component.ts 设置为一个值
  • 你应该检查你的代码是否有错别字,尤其是与大小写相关的。看看这些:“GetlinkName”和“SetLikName”。 “L”缺少一个字符和不同的大小写。此外,当使用getset 时,您将省略“set”前缀。它只是“设置链接名称(值:字符串){...}”
猜你喜欢
  • 2018-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-16
  • 2020-10-09
  • 1970-01-01
  • 2016-08-23
  • 1970-01-01
相关资源
最近更新 更多