使用服务在角度组件之间调用方法不起作用

Posted

技术标签:

【中文标题】使用服务在角度组件之间调用方法不起作用【英文标题】:Calling methods between components in angular using service not working 【发布时间】:2017-11-17 19:59:19 【问题描述】:

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

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

bottombar.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() 



我试图从上面的组件中调用 SideDrawerGettingStartedComponent 中的一个方法,该方法位于下面,它将触发一个打开侧抽屉的方法

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

sidedrawer.component.ts

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();
    

共享服务如下

bottombar.service.ts

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.component.ts 关联的 html,其中包含一个按钮。点击它会触发 bottombar.component.ts

中的 openDrawer() 函数

我可以在我的服务文件中看到控制台值,但不知何故它没有触发 sidedrawer.component.ts

中的订阅

没有错误,因此很难找到导致问题的确切原因。

另外我已经在 ngModule 的提供者中声明了我的服务以避免单例问题。

这里有什么我遗漏的吗?

提前致谢

【问题讨论】:

Angular - shared service between components doesn't work的可能重复 我尝试了在ngModule 中声明服务的解决方案,正如我在最后几行中提到的,即使在根目录提供服务后它也无法正常工作 仔细阅读答案,您仍然在@Component注解中重新提供了服务 您确定您的sidedrawer 组件已加载吗? @Abrar EventEmitter 仅适用于两个组件具有parent-child 关系的情况。 【参考方案1】:

在您的共享服务中,您可以传递status:boolean,而不是在这里传递null this.sideDrawerMethodSource.next(null)。在你的 bottombar.service.ts -

callSideDrawerMethod(status:boolean)
    this.sideDrawerMethodSource.next(status);

现在,在 bottombar.component.ts 中,在调用方法时传递一个状态 -

this.bottomBarService.callSideDrawerMethod(true);

在您的 sidedrawer.component.ts 中,传递 status 参数 -

  this.bottomBarService.sideDrawerMethodCalled$.subscribe((status) => 
        console.log("subscribed")
        alert("hello")
        this.openDrawer()
      )

并且不要在构造函数中订阅,而是将代码放在ngOnInit()生命周期钩子中。

希望这会有所帮助。

【讨论】:

这与@AmitChigadani 对问题的评论一起使用。【参考方案2】:

您似乎错过了在sideDrawerMethodCalled 旁边附加'$'

试试下面的代码:

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

【讨论】:

我在私有sideDrawerMethodSource = new Subject&lt;any&gt;(); 中的变量没有$。所以我没有那样使用它。无论如何我尝试附加$,仍然无法正常工作

以上是关于使用服务在角度组件之间调用方法不起作用的主要内容,如果未能解决你的问题,请参考以下文章

在路线更改和新组件加载不起作用后以角度滚动到顶部

使用ajax调用的角度保存变量到laravel会话不起作用

使用服务不起作用的 2 个组件之间的交互 ​​Angular 6/7

调用服务时异步调用不起作用 - Angular 8

CSS 在我的角度组件中不起作用

reactjs 中的组件之间的转换不起作用并且没有应用 css 属性