Angular 5:在组件之间共享数据的服务(跨模块)?

时间:2017-12-18 10:46:03

标签: angular dependency-injection angular-material2 angular-services angular-module

我有这个简单的服务,它是两个模块中的provider

@Injectable()
export class PlatformPickerService {
  platforms: string[] = [
    'macOS', 'Linux', 'Windows'
  ];
  public platform: string;

  constructor() {
    this.platform = this.platforms[1];
  }

  public getPlatform(): string {
    const platform = localStorage.getItem('platform');
    return platform == null ? this.platform : platform;
  }

  public setPlatform(platform: string) {
    this.platform = platform;
    localStorage.setItem('platform', platform);
  }
}

不幸的是,我无处使用它获得了所选的值。在模块外部使用它只给出默认值,在其模块中使用它不会给出任何值。

完整测试用例:https://stackblitz.com/edit/angular-aru94g-2djexv

4 个答案:

答案 0 :(得分:1)

服务是注射器范围内的单件。将PlatformPickerService定义为应用程序模块或根模块中的提供程序,并将其设置为单例服务。这将是应用程序范围的单件服务。

好的,您的PlatformPickerComponent问题。您必须将所选值发送到updateService。

  • 属性绑定 - [] =>组件到模板 - 单向绑定, 更改值不会更新组件

    中的属性
      

    [数值] = “platformSelected”

  • 事件绑定 - ()=>模板到组件

      

    (变化)= “updateService($ event.value)”

  • 此示例将PlatformPickerService移至app模块并设置为应用程序作用域提供程序。

请检查sample appdemo

在PlatformPickerService中设置默认平台值,每当更改它时,它会在下拉框中反映为选定值。

  constructor() {
    this.platform = this.platforms[4];
  }

答案 1 :(得分:1)

最后让它发挥作用:https://angular-aru94g-w6qy21.stackblitz.ioedit

主要变化是:

组件

updateService(event: any) {
    if (event.value != null) this.platformPickerService.setPlatform(event.value);
}
<mat-form-field>
  <mat-select placeholder="Platform" shouldLabelFloat="false"
              [(ngModel)]="platformSelectd"
              (selectionChange)=updateService($event)>
    <mat-option *ngFor="let platform of platformPickerService.platforms"
                [value]=platform>
      {{ platform }}
    </mat-option>
  </mat-select>
</mat-form-field>

模块

  • 在一个模块中只有PlatformPickerService(app.module)

现在是时候再次尝试重写setter / getter,看看它是否有效(setPlatformset platform)= 3

答案 2 :(得分:0)

你错过了PlatformPickerComponent中的双向约束 将FormsModule的导入添加到PlatformPickerModule并更改PlatformPickerComponent,如下所示:

<mat-form-field>
  <mat-select placeholder="Platform" shouldLabelFloat="false" [(ngModel)]="platform">
    <mat-option *ngFor="let platform of platformPickerService.platforms"
                [value]="platform">
      {{ platform }}
    </mat-option>
  </mat-select>
</mat-form-field>



import {AfterViewInit, Component, OnInit} from '@angular/core';

import {PlatformPickerService} from './platform-picker.service';

@Component({
  selector: 'platform-picker',
  templateUrl: './platform-picker.component.html',
  styleUrls: ['./platform-picker.component.css']
})
export class PlatformPickerComponent implements OnInit, AfterViewInit {
  private _platform: string;

  constructor(public platformPickerService: PlatformPickerService) {
  }

  ngOnInit() {
    this._platform = this.platformPickerService.getPlatform();
  }

  ngAfterViewInit() {
  }

   get platform(): string {
    return this._platform;
  }

  set platform(value: string) {
    if (value != null) {
      this.platformPickerService.setPlatform(value);
      this._platform = value;
    }
  }
}

答案 3 :(得分:0)

我对您现有的代码进行了一些更改。 如果您使用双向绑定,则可以跳过ngModelChange 否则,使用单向绑定和ngModelChange,如下所示。

<mat-form-field>
  <mat-select [ngModel]="selected" (ngModelChange)="updateService($event)"  placeholder="Platform" shouldLabelFloat="false" [(value)]="selected">
    <mat-option *ngFor="let platform of platformPickerService.platforms"
                [value]="platform">
      {{ platform }}
    </mat-option>
  </mat-select>
</mat-form-field>

并按以下方式更新Service函数

updateService(newPlatform) {
    console.log(newPlatform);
    if (newPlatform != null) {
      this.selected = newPlatform;
      this.platformPickerService.setPlatform(this.selected);
    }
  }

你可以在这里查看代码 https://angular-aru94g-agtn1m.stackblitz.io