简体   繁体   English

Angular 7将变量从component传递到app.component.ts

[英]Angular 7 passing a variable from component to app.component.ts

In an effort to pass a variable into app.component.ts from another component I created a service (see Global.service.ts below.) 为了将变量从另一个组件传递到app.component.ts中,我创建了一个服务(请参阅下面的Global.service.ts。)

This works well when my nav.component.ts calls the service. 当我的nav.component.ts调用该服务时,此方法效果很好。 However, it doesn't work in app.component.ts. 但是,它在app.component.ts中不起作用。 I don't understand why, as the code is the same (see app.component.ts below.) 我不明白为什么,因为代码相同(请参见下面的app.component.ts。)

Nav.component.ts is in a module (global.module.ts). Nav.component.ts在模块(global.module.ts)中。 global.module.ts has been added to the imports [] in app.module.ts. global.module.ts已添加到app.module.ts中的import []。

Global.service.ts Global.service.ts

@Injectable()
export class GlobalService {
  private handleError: HandleError;
  isOpen = false;

  private _change: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

  constructor(
   private http: HttpClient,
   httpErrorHandler: HttpErrorHandler
  ) {

  this.handleError = httpErrorHandler.createHandleError('GlobalService');
 }

get change(): Observable<boolean> {
  return this._change.asObservable();
}

toggle() {
 this.isOpen = !this.isOpen;
 this._change.next(this.isOpen);
}

}

app.component.ts app.component.ts

import { Component, OnInit } from '@angular/core';
import { GlobalService } from './globals/global.service';

@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  isOpen = true;

  constructor(
    private _globalService: GlobalService,
  ) {
 }

ngOnInit(): void {
  console.log("foo bar");

  this._globalService.change.subscribe(isOpen => {
    this.isOpen = isOpen;
    console.log(this.isOpen);
  });

 }
}

nav.component.ts nav.component.ts

ngOnInit(): void {

//
this.getNav();

  this._globalService.change.subscribe(isOpen => {
    this.isOpen = isOpen;
    this.NavToggle(this.isOpen);
  });

}

//Toggle
hideShowSidebar() {
    this._globalService.toggle();
}

The @Output (and @Input ) decorators are typically used for attributes/properties of components/elements to detect events (and assign values), I would say that it would not be the best way for a Service to emit an update to a Component. @Output (和@Input )装饰器通常用于组件/元素的属性/属性以检测事件(并分配值),我想这不是服务向组件发出更新的最佳方法。 For that you could use a simple BehaviorSubject and just a little change to your service. 为此,您可以使用一个简单的BehaviorSubject,并对服务进行一些更改。

@Injectable()
export class GlobalService {
 private handleError: HandleError;
 isOpen = false;
 private _change: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

  constructor(
   private http: HttpClient,
   httpErrorHandler: HttpErrorHandler
  ) {

  this.handleError = httpErrorHandler.createHandleError('GlobalService');
 }

 get change(): Observable<boolean> {
  return this._change.asObseravble();
 }

 toggle() {
  this.isOpen = !this.isOpen;
  this._change.next(this.isOpen);
 }
}

Since the _change BehaviorSubject provides as a source of truth for components/classes outside of itself, we do not want to expose it (as it can be easily changed). 由于_change BehaviorSubject作为自身外部的组件/类的真实来源,因此我们不想公开它(因为可以轻松更改)。 That is why we provide it through the get ter as an Observable. 这就是为什么我们通过它提供get之三是可观察的。 This should work however if you have the service imported into the providers of multiple modules, you may have multiple instances of the service (and they wouldn't all have the same data). 这应该可行,但是如果您将服务导入到多个模块的提供程序中,则您可能具有该服务的多个实例(而且它们都不会具有相同的数据)。 If that is the case it would be best to only have your service declared in only your AppModule . 如果是这种情况,最好只在AppModule声明服务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM