Angular在兄弟组件之间共享Sigmajs图。

huangapple go评论138阅读模式
英文:

Angular share sigmajs graph between sibling components

问题

sigma.component.ts中创建了一个sigma实例。我的问题是,我如何与兄弟组件search.component.ts共享sigma实例?

通常情况下,我会使用@Input和@Output装饰器以及事件发射器来通过父组件作为桥梁共享图形。但是在sigma.component.ts模板中只有

标签,我无法通过这种方式找到解决方案。我需要sigma实例在sigma.component.ts中创建/更改时随时共享。

英文:

I am following this example to display a sigmajs graph in angular: https://github.com/sim51/ng-sigma-example.

app.component.ts

  1. import { Component } from "@angular/core";
  2. import Graph from "graphology";
  3. import erdosRenyi from "graphology-generators/random/erdos-renyi";
  4. import circularLayout from "graphology-layout/circular";
  5. @Component({
  6. selector: "app-root",
  7. templateUrl: "./app.component.html",
  8. styleUrls: ["./app.component.scss"]
  9. })
  10. export class AppComponent {
  11. title = "ng-sigma-example";
  12. graph: Graph;
  13. constructor() {
  14. this.graph = erdosRenyi(Graph, { order: 100, probability: 0.1 });
  15. circularLayout.assign(this.graph);
  16. }
  17. }

sigma.component.ts

  1. import {
  2. Component,
  3. OnDestroy,
  4. AfterViewInit,
  5. ElementRef,
  6. ViewChild,
  7. Input
  8. } from "@angular/core";
  9. import Graph from "graphology";
  10. import { Sigma } from "sigma";
  11. @Component({
  12. selector: "sigma",
  13. template: "<div #container></div>",
  14. styleUrls: ["./sigma.component.scss"]
  15. })
  16. export class SigmaComponent implements AfterViewInit, OnDestroy {
  17. @ViewChild("container") container: ElementRef | null = null;
  18. @Input("graph") graph: Graph = new Graph();
  19. sigma?: Sigma;
  20. ngAfterViewInit(): void {
  21. if (this.container)
  22. this.sigma = new Sigma(this.graph, this.container.nativeElement);
  23. }
  24. ngOnDestroy(): void {
  25. if (this.sigma) {
  26. this.sigma.kill();
  27. }
  28. }
  29. }

app.component.html

  1. <sigma [graph]="graph"> </sigma>

search.component.ts

  1. import {
  2. Component,
  3. OnInit,
  4. ElementRef,
  5. ViewChild,
  6. Input} from '@angular/core';
  7. import { Sigma } from "sigma";
  8. import Graph from "graphology";
  9. @Component({
  10. selector: 'app-search',
  11. templateUrl: './search.component.html',
  12. styleUrls: ['./search.component.scss']
  13. })
  14. export class SearchComponent implements OnInit {
  15. @ViewChild("container") container: ElementRef | null = null; // could be null -> hence needs if statement
  16. @Input("graph") graph: Graph = new Graph();
  17. @Input() // should give me the sigma instance from sigma.component.ts
  18. constructor() {
  19. }
  20. ngOnInit(): void {
  21. // should give me access to sigma instance graph
  22. console.log(this.renderer?.getGraph())
  23. }
  24. }

In sigma.component.ts a sigma instance is created. My questions is, how can I share the sigma instance with a sibling component search.component.ts?

Normally, I would use @input and @output decorators with an event emitter to share the graph using the parent component as a bridge. But I only have div tags in the sigma.component.ts template and I was unable to get a solution that way. I need the sigma instance to be shared any time a new sigma instance is created/changed in sigma.component.ts

答案1

得分: 0

另一种在组件之间共享数据的方法是使用可观察对象(Observables)的服务。您可以创建一个服务,其中包含一个可以从任何地方更新的值,并可以从任何地方监听这些更改。您可以在https://angular.io/guide/observables 上阅读更多信息。

sigmaService.ts

  1. sigmaObservable: Subject<Sigma> = new Subject();
  2. setSigma(receivedSigma: Sigma): {
  3. this.sigmaObservable.next(this.receivedSigma);
  4. }

sigma.component.ts(不要忘记导入该服务并将其添加到构造函数中)

  1. ngAfterViewInit(): void {
  2. if (this.container) {
  3. this.sigma = new Sigma(this.graph, this.container.nativeElement);
  4. this.sigmaService.setSigma(this.sigma); // 或者创建一个单独的变量,并将其设置为this.sigma和这个
  5. }
  6. }

search.component.ts(创建一个订阅变量和一个sigma变量来填充。当使用订阅接收到新值时,请在ngOnInit中填充,并在ngOnDestroy中不要忘记取消订阅)

  1. _subscription: Subscription = Subscription.EMPTY;
  2. sigmaInSearch: Sigma;
  3. ngOnInit(): void {
  4. this._subscription = this.sigmaService.sigmaObservable.subscribe((sigmaValue) => {
  5. this.sigmaInSearch = sigmaValue;
  6. });
  7. }
  8. ngOnDestroy(): void {
  9. this._subscription.unsubscribe();
  10. }
英文:

Another way of sharing data between components is with a service using Observables. You can make a service which has a value that can be updated from anywhere and listen to those changes from anywhere. You can read more on https://angular.io/guide/observables.

sigmaService.ts

  1. sigmaObservable: Subject&lt;Sigma&gt; = new Subject();
  2. setSigma(receivedSigma: Sigma): {
  3. this.sigmaObservable.next(this.receivedSigma);
  4. }

sigma.component.ts (don't forget to import the service and add it to the constructor)

  1. ngAfterViewInit(): void {
  2. if (this.container) {
  3. this.sigma = new Sigma(this.graph, this.container.nativeElement);
  4. this.sigmaService.setSigma(this.sigma); // or create a separate variable and set it to both this.sigma and this one
  5. }
  6. }

search.component.ts (create a subscription variable and the sigma variable to populate. Populate on ngOnInit when the new value is received with a subscription and don't forget to unsubbscribe onDestroy)

  1. _subscription: Subscription = Subscription.EMPTY;
  2. sigmaInSearch: Sigma;
  3. ngOnInit(): void {
  4. this._subscription = this.sigmaService.sigmaObservable.subscribe((sigmaValue) =&gt; {
  5. this.sigmaInSearch = sigmaValue;
  6. });
  7. }
  8. ngOnDestroy(): void {
  9. this._subscription.unsubscribe();
  10. }

huangapple
  • 本文由 发表于 2023年3月7日 02:39:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75654625.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定