使用服务在angular中的组件之间调用方法不起作用

使用服务在angular中的组件之间调用方法不起作用,angular,angular2-services,angular2-nativescript,nativescript-telerik-ui,injectable,Angular,Angular2 Services,Angular2 Nativescript,Nativescript Telerik Ui,Injectable,我试图使用可注入服务从另一个组件调用一个组件中的方法 我的第一个组件(我正在从这个组件调用其他组件中的方法) 底部栏.component.ts import { Component, ElementRef, OnInit, ViewChild, AfterViewInit, ChangeDetectorRef, EventEmitter, Input, Output } from "@angular/core"; import { Router } from "@angular/router";

我试图使用可注入服务从另一个组件调用一个组件中的方法

我的第一个组件(我正在从这个组件调用其他组件中的方法)

底部栏.component.ts

import { Component, ElementRef, OnInit, ViewChild, AfterViewInit, ChangeDetectorRef, EventEmitter, Input, Output } from "@angular/core";
import { Router } from "@angular/router";
import { Label } from "ui/label";
import { BottomBarService } from '../../services/bottombarservice/bottombar.service';

@Component({
  selector: "bottom-bar",
  templateUrl: "./components/bottombar/bottombar.html",
  styleUrls:["./components/bottombar/bottombar-common.css", "./components/bottombar/bottombar.css"],
  //providers: [BottomBarService]
})

export class bottombarComponent implements OnInit {

  constructor(private bottomBarService: BottomBarService) {

  }

  openDrawer(){
    this.bottomBarService.callSideDrawerMethod();
  }
  ngOnInit() {}


}
import { Component, ViewChild, OnInit, AfterViewInit, ChangeDetectorRef } from "@angular/core";
import { Page } from "ui/page";
import { ActionItem } from "ui/action-bar";
import { Observable } from "data/observable";
import { RadSideDrawerComponent, SideDrawerType } from "nativescript-telerik-ui-pro/sidedrawer/angular";
import { RadSideDrawer } from 'nativescript-telerik-ui-pro/sidedrawer';
import { BottomBarService } from '../../services/bottombarservice/bottombar.service';

@Component({
    // moduleId: module.id,
    selector: "tk-sidedrawer-getting-started",
    templateUrl: "./components/sidedrawer/sidedrawer.html",
    styleUrls: ['./components/sidedrawer/sidedrawer.css'],
    //providers: [BottomBarService]
})
export class SideDrawerGettingStartedComponent implements AfterViewInit, OnInit {
    private _mainContentText: string;

    constructor(private _changeDetectionRef: ChangeDetectorRef,private bottomBarService: BottomBarService) {
      this.bottomBarService.sideDrawerMethodCalled$.subscribe(() => {
        console.log("subscribed")
        alert("hello")
        this.openDrawer()
      })
    }

    @ViewChild(RadSideDrawerComponent) public drawerComponent: RadSideDrawerComponent;
    private drawer: RadSideDrawer;

    ngAfterViewInit() {
        this.drawer = this.drawerComponent.sideDrawer;
        this._changeDetectionRef.detectChanges();
    }

    ngOnInit() {
        this.mainContentText = "SideDrawer for NativeScript can be easily setup in the HTML definition of your page by defining tkDrawerContent and tkMainContent. The component has a default transition and position and also exposes notifications related to changes in its state. Swipe from left to open side drawer.";
    }

    get mainContentText() {
        return this._mainContentText;
    }

    set mainContentText(value: string) {
        this._mainContentText = value;
    }

    public openDrawer() {
        console.log("triggered openDrawer in main component")
        this.drawer.showDrawer();
    }

    public onCloseDrawerTap() {
       this.drawer.closeDrawer();
    }
}
import { Subject }    from 'rxjs/Subject';
import { Injectable } from '@angular/core';

@Injectable()
export class BottomBarService{
    private sideDrawerMethodSource = new Subject<any>();
    sideDrawerMethodCalled$ = this.sideDrawerMethodSource.asObservable();

    callSideDrawerMethod(){
        console.log("Inside service bottomBar")
        this.sideDrawerMethodSource.next(null);
        console.log("after")
    }
}
从上面的组件中,我试图调用SideDrawerGettingStartedComponent中的一个方法,该方法位于下面,它将触发打开SideDrawer的方法

我的第二个组件(其中存在被调用的方法)

sidedrawer.component.ts

import { Component, ElementRef, OnInit, ViewChild, AfterViewInit, ChangeDetectorRef, EventEmitter, Input, Output } from "@angular/core";
import { Router } from "@angular/router";
import { Label } from "ui/label";
import { BottomBarService } from '../../services/bottombarservice/bottombar.service';

@Component({
  selector: "bottom-bar",
  templateUrl: "./components/bottombar/bottombar.html",
  styleUrls:["./components/bottombar/bottombar-common.css", "./components/bottombar/bottombar.css"],
  //providers: [BottomBarService]
})

export class bottombarComponent implements OnInit {

  constructor(private bottomBarService: BottomBarService) {

  }

  openDrawer(){
    this.bottomBarService.callSideDrawerMethod();
  }
  ngOnInit() {}


}
import { Component, ViewChild, OnInit, AfterViewInit, ChangeDetectorRef } from "@angular/core";
import { Page } from "ui/page";
import { ActionItem } from "ui/action-bar";
import { Observable } from "data/observable";
import { RadSideDrawerComponent, SideDrawerType } from "nativescript-telerik-ui-pro/sidedrawer/angular";
import { RadSideDrawer } from 'nativescript-telerik-ui-pro/sidedrawer';
import { BottomBarService } from '../../services/bottombarservice/bottombar.service';

@Component({
    // moduleId: module.id,
    selector: "tk-sidedrawer-getting-started",
    templateUrl: "./components/sidedrawer/sidedrawer.html",
    styleUrls: ['./components/sidedrawer/sidedrawer.css'],
    //providers: [BottomBarService]
})
export class SideDrawerGettingStartedComponent implements AfterViewInit, OnInit {
    private _mainContentText: string;

    constructor(private _changeDetectionRef: ChangeDetectorRef,private bottomBarService: BottomBarService) {
      this.bottomBarService.sideDrawerMethodCalled$.subscribe(() => {
        console.log("subscribed")
        alert("hello")
        this.openDrawer()
      })
    }

    @ViewChild(RadSideDrawerComponent) public drawerComponent: RadSideDrawerComponent;
    private drawer: RadSideDrawer;

    ngAfterViewInit() {
        this.drawer = this.drawerComponent.sideDrawer;
        this._changeDetectionRef.detectChanges();
    }

    ngOnInit() {
        this.mainContentText = "SideDrawer for NativeScript can be easily setup in the HTML definition of your page by defining tkDrawerContent and tkMainContent. The component has a default transition and position and also exposes notifications related to changes in its state. Swipe from left to open side drawer.";
    }

    get mainContentText() {
        return this._mainContentText;
    }

    set mainContentText(value: string) {
        this._mainContentText = value;
    }

    public openDrawer() {
        console.log("triggered openDrawer in main component")
        this.drawer.showDrawer();
    }

    public onCloseDrawerTap() {
       this.drawer.closeDrawer();
    }
}
import { Subject }    from 'rxjs/Subject';
import { Injectable } from '@angular/core';

@Injectable()
export class BottomBarService{
    private sideDrawerMethodSource = new Subject<any>();
    sideDrawerMethodCalled$ = this.sideDrawerMethodSource.asObservable();

    callSideDrawerMethod(){
        console.log("Inside service bottomBar")
        this.sideDrawerMethodSource.next(null);
        console.log("after")
    }
}
共享服务如下所示

bottombar.service.ts

import { Component, ElementRef, OnInit, ViewChild, AfterViewInit, ChangeDetectorRef, EventEmitter, Input, Output } from "@angular/core";
import { Router } from "@angular/router";
import { Label } from "ui/label";
import { BottomBarService } from '../../services/bottombarservice/bottombar.service';

@Component({
  selector: "bottom-bar",
  templateUrl: "./components/bottombar/bottombar.html",
  styleUrls:["./components/bottombar/bottombar-common.css", "./components/bottombar/bottombar.css"],
  //providers: [BottomBarService]
})

export class bottombarComponent implements OnInit {

  constructor(private bottomBarService: BottomBarService) {

  }

  openDrawer(){
    this.bottomBarService.callSideDrawerMethod();
  }
  ngOnInit() {}


}
import { Component, ViewChild, OnInit, AfterViewInit, ChangeDetectorRef } from "@angular/core";
import { Page } from "ui/page";
import { ActionItem } from "ui/action-bar";
import { Observable } from "data/observable";
import { RadSideDrawerComponent, SideDrawerType } from "nativescript-telerik-ui-pro/sidedrawer/angular";
import { RadSideDrawer } from 'nativescript-telerik-ui-pro/sidedrawer';
import { BottomBarService } from '../../services/bottombarservice/bottombar.service';

@Component({
    // moduleId: module.id,
    selector: "tk-sidedrawer-getting-started",
    templateUrl: "./components/sidedrawer/sidedrawer.html",
    styleUrls: ['./components/sidedrawer/sidedrawer.css'],
    //providers: [BottomBarService]
})
export class SideDrawerGettingStartedComponent implements AfterViewInit, OnInit {
    private _mainContentText: string;

    constructor(private _changeDetectionRef: ChangeDetectorRef,private bottomBarService: BottomBarService) {
      this.bottomBarService.sideDrawerMethodCalled$.subscribe(() => {
        console.log("subscribed")
        alert("hello")
        this.openDrawer()
      })
    }

    @ViewChild(RadSideDrawerComponent) public drawerComponent: RadSideDrawerComponent;
    private drawer: RadSideDrawer;

    ngAfterViewInit() {
        this.drawer = this.drawerComponent.sideDrawer;
        this._changeDetectionRef.detectChanges();
    }

    ngOnInit() {
        this.mainContentText = "SideDrawer for NativeScript can be easily setup in the HTML definition of your page by defining tkDrawerContent and tkMainContent. The component has a default transition and position and also exposes notifications related to changes in its state. Swipe from left to open side drawer.";
    }

    get mainContentText() {
        return this._mainContentText;
    }

    set mainContentText(value: string) {
        this._mainContentText = value;
    }

    public openDrawer() {
        console.log("triggered openDrawer in main component")
        this.drawer.showDrawer();
    }

    public onCloseDrawerTap() {
       this.drawer.closeDrawer();
    }
}
import { Subject }    from 'rxjs/Subject';
import { Injectable } from '@angular/core';

@Injectable()
export class BottomBarService{
    private sideDrawerMethodSource = new Subject<any>();
    sideDrawerMethodCalled$ = this.sideDrawerMethodSource.asObservable();

    callSideDrawerMethod(){
        console.log("Inside service bottomBar")
        this.sideDrawerMethodSource.next(null);
        console.log("after")
    }
}
从'rxjs/Subject'导入{Subject};
从“@angular/core”导入{Injectable};
@可注射()
出口级服务{
private sideDrawerMethodSource=新主题();
sideDrawerMethodCalled$=this.sideDrawerMethodSource.asObservable();
callSideDrawerMethod(){
控制台日志(“内部服务底部栏”)
this.sideDrawerMethodSource.next(null);
console.log(“之后”)
}
}
问题

我有一个与bottombar.component.ts相关联的html,它包含一个按钮。点击它将触发bottombar.component.ts中的openDrawer()函数

import { Component, ElementRef, OnInit, ViewChild, AfterViewInit, ChangeDetectorRef, EventEmitter, Input, Output } from "@angular/core";
import { Router } from "@angular/router";
import { Label } from "ui/label";
import { BottomBarService } from '../../services/bottombarservice/bottombar.service';

@Component({
  selector: "bottom-bar",
  templateUrl: "./components/bottombar/bottombar.html",
  styleUrls:["./components/bottombar/bottombar-common.css", "./components/bottombar/bottombar.css"],
  //providers: [BottomBarService]
})

export class bottombarComponent implements OnInit {

  constructor(private bottomBarService: BottomBarService) {

  }

  openDrawer(){
    this.bottomBarService.callSideDrawerMethod();
  }
  ngOnInit() {}


}
import { Component, ViewChild, OnInit, AfterViewInit, ChangeDetectorRef } from "@angular/core";
import { Page } from "ui/page";
import { ActionItem } from "ui/action-bar";
import { Observable } from "data/observable";
import { RadSideDrawerComponent, SideDrawerType } from "nativescript-telerik-ui-pro/sidedrawer/angular";
import { RadSideDrawer } from 'nativescript-telerik-ui-pro/sidedrawer';
import { BottomBarService } from '../../services/bottombarservice/bottombar.service';

@Component({
    // moduleId: module.id,
    selector: "tk-sidedrawer-getting-started",
    templateUrl: "./components/sidedrawer/sidedrawer.html",
    styleUrls: ['./components/sidedrawer/sidedrawer.css'],
    //providers: [BottomBarService]
})
export class SideDrawerGettingStartedComponent implements AfterViewInit, OnInit {
    private _mainContentText: string;

    constructor(private _changeDetectionRef: ChangeDetectorRef,private bottomBarService: BottomBarService) {
      this.bottomBarService.sideDrawerMethodCalled$.subscribe(() => {
        console.log("subscribed")
        alert("hello")
        this.openDrawer()
      })
    }

    @ViewChild(RadSideDrawerComponent) public drawerComponent: RadSideDrawerComponent;
    private drawer: RadSideDrawer;

    ngAfterViewInit() {
        this.drawer = this.drawerComponent.sideDrawer;
        this._changeDetectionRef.detectChanges();
    }

    ngOnInit() {
        this.mainContentText = "SideDrawer for NativeScript can be easily setup in the HTML definition of your page by defining tkDrawerContent and tkMainContent. The component has a default transition and position and also exposes notifications related to changes in its state. Swipe from left to open side drawer.";
    }

    get mainContentText() {
        return this._mainContentText;
    }

    set mainContentText(value: string) {
        this._mainContentText = value;
    }

    public openDrawer() {
        console.log("triggered openDrawer in main component")
        this.drawer.showDrawer();
    }

    public onCloseDrawerTap() {
       this.drawer.closeDrawer();
    }
}
import { Subject }    from 'rxjs/Subject';
import { Injectable } from '@angular/core';

@Injectable()
export class BottomBarService{
    private sideDrawerMethodSource = new Subject<any>();
    sideDrawerMethodCalled$ = this.sideDrawerMethodSource.asObservable();

    callSideDrawerMethod(){
        console.log("Inside service bottomBar")
        this.sideDrawerMethodSource.next(null);
        console.log("after")
    }
}
我可以在我的服务文件中看到consoled值,但不知何故,它没有触发sidedrawer.component.ts中的subscribe

import { Component, ElementRef, OnInit, ViewChild, AfterViewInit, ChangeDetectorRef, EventEmitter, Input, Output } from "@angular/core";
import { Router } from "@angular/router";
import { Label } from "ui/label";
import { BottomBarService } from '../../services/bottombarservice/bottombar.service';

@Component({
  selector: "bottom-bar",
  templateUrl: "./components/bottombar/bottombar.html",
  styleUrls:["./components/bottombar/bottombar-common.css", "./components/bottombar/bottombar.css"],
  //providers: [BottomBarService]
})

export class bottombarComponent implements OnInit {

  constructor(private bottomBarService: BottomBarService) {

  }

  openDrawer(){
    this.bottomBarService.callSideDrawerMethod();
  }
  ngOnInit() {}


}
import { Component, ViewChild, OnInit, AfterViewInit, ChangeDetectorRef } from "@angular/core";
import { Page } from "ui/page";
import { ActionItem } from "ui/action-bar";
import { Observable } from "data/observable";
import { RadSideDrawerComponent, SideDrawerType } from "nativescript-telerik-ui-pro/sidedrawer/angular";
import { RadSideDrawer } from 'nativescript-telerik-ui-pro/sidedrawer';
import { BottomBarService } from '../../services/bottombarservice/bottombar.service';

@Component({
    // moduleId: module.id,
    selector: "tk-sidedrawer-getting-started",
    templateUrl: "./components/sidedrawer/sidedrawer.html",
    styleUrls: ['./components/sidedrawer/sidedrawer.css'],
    //providers: [BottomBarService]
})
export class SideDrawerGettingStartedComponent implements AfterViewInit, OnInit {
    private _mainContentText: string;

    constructor(private _changeDetectionRef: ChangeDetectorRef,private bottomBarService: BottomBarService) {
      this.bottomBarService.sideDrawerMethodCalled$.subscribe(() => {
        console.log("subscribed")
        alert("hello")
        this.openDrawer()
      })
    }

    @ViewChild(RadSideDrawerComponent) public drawerComponent: RadSideDrawerComponent;
    private drawer: RadSideDrawer;

    ngAfterViewInit() {
        this.drawer = this.drawerComponent.sideDrawer;
        this._changeDetectionRef.detectChanges();
    }

    ngOnInit() {
        this.mainContentText = "SideDrawer for NativeScript can be easily setup in the HTML definition of your page by defining tkDrawerContent and tkMainContent. The component has a default transition and position and also exposes notifications related to changes in its state. Swipe from left to open side drawer.";
    }

    get mainContentText() {
        return this._mainContentText;
    }

    set mainContentText(value: string) {
        this._mainContentText = value;
    }

    public openDrawer() {
        console.log("triggered openDrawer in main component")
        this.drawer.showDrawer();
    }

    public onCloseDrawerTap() {
       this.drawer.closeDrawer();
    }
}
import { Subject }    from 'rxjs/Subject';
import { Injectable } from '@angular/core';

@Injectable()
export class BottomBarService{
    private sideDrawerMethodSource = new Subject<any>();
    sideDrawerMethodCalled$ = this.sideDrawerMethodSource.asObservable();

    callSideDrawerMethod(){
        console.log("Inside service bottomBar")
        this.sideDrawerMethodSource.next(null);
        console.log("after")
    }
}
没有错误,因此很难找到问题的确切原因

此外,我已在ngModule的提供商中声明了我的服务,以避免单例问题

这里有我遗漏的东西吗


提前感谢

您似乎错过了将
'$'
附加到
侧抽屉方法调用的旁边

请尝试以下代码:

callSideDrawerMethod(){
        console.log("Inside service bottomBar")
        this.sideDrawerMethodSource$.next(null);
        console.log("after")
    }

在共享服务中,您可以传递一个
状态:boolean
,而不是在此处传递
null
this.sideDrawerMethodSource.next(null)。在您的底部栏.service.ts中-

callSideDrawerMethod(status:boolean){
    this.sideDrawerMethodSource.next(status);
}
现在,在底部栏.component.ts中,在调用该方法时传递一个状态-

this.bottomBarService.callSideDrawerMethod(true);
在您的侧抽屉.component.ts中,传递一个
状态
参数-

  this.bottomBarService.sideDrawerMethodCalled$.subscribe((status) => {
        console.log("subscribed")
        alert("hello")
        this.openDrawer()
      })
将代码放入
ngOnInit()
lifecyclehook,而不是订阅构造函数


希望这有帮助。

可能重复我尝试过的解决方案,即在
ngModule中声明服务
,正如我在最后几行中提到的,即使在根节点提供服务后,它也不起作用仔细阅读答案,您仍然在
@组件
注释中重新提供了您的服务。是否确实加载了
侧抽屉
组件?@Abrar
EventEmitter
仅在两个组件具有
父子关系时才适用。行private中的my变量
sideDrawerMethodSource=new Subject()没有
$
。所以我没有那样使用它。不管怎样,我试着添加
$
,但它仍然不起作用,这与@AmitChigadani对问题的评论一起起作用。