使用独特的服务在祖父母和孙子组件之间进行通信

时间:2018-02-01 05:25:30

标签: angular angular5

我想将祖父母的数据传递给孙子。使用@Input似乎很麻烦,因为我必须使用它两次 - 我也相信它会使重构更难,例如这些组件成为兄弟姐妹。

换句话说,我想避免两次使用@Input,一个在孩子中,一个在孙子中,用于传递相同的数据。我目前更喜欢使用共享服务来共享数据

这是HTML:

//祖父母

<div *ngIf="daPanel.expanded === true">
 <div *ngFor="let e of elements;">
  <app-history-item-tab-group></app-history-item-tab-group>
 </div>
</div>

// child

<div>
  <mat-tab-group>
    <mat-tab label="Settings">
      <app-history-settings></app-history-settings>
    </mat-tab>
    <mat-tab label="Events List">
      <app-history-events-list></app-history-events-list>
    </mat-tab>
    <mat-tab label="Generated Code">
      <app-history-generated-code></app-history-generated-code>
    </mat-tab>
  </mat-tab-group>
</div>

//孙子

<div class="language-js">

  <mat-card>

    <button id="copy-code-btn" style="float:right;" 
            mat-raised-button (click)="copyCodeToClipboard()">Copy Code to Clipboard</button>

    <button style="float:right;" mat-raised-button>Save Code to File</button>

    <mat-card-title>Here is your generated code</mat-card-title>
    <mat-card-subtitle>JavaScript</mat-card-subtitle>


    <mat-card-content [style.overflow]="'auto'" [style.height.px]="'500'">
      <pre [innerHTML]="highlightedCode"></pre>
    </mat-card-content>

    <mat-card-actions>
      <button mat-button>LIKE</button>
      <button mat-button>SHARE</button>
    </mat-card-actions>
    <mat-card-footer></mat-card-footer>
  </mat-card>

</div>

与使用@Input传递数据相反,我宁愿在组件之间共享服务的唯一实例,但我不知道如何做到这一点。

确切地说 - 理想情况下,我可以为祖父母创建一个独特的服务实例,并在祖父母,孩子和孙子中分享对该独特服务的引用......但是如何?

这是祖父母组成部分:

@Component({
  moduleId: module.id,
  templateUrl: './history.component.html',
  styleUrls: ['./history.component.scss'],
  encapsulation: ViewEncapsulation.None,
  preserveWhitespaces: false,
})

export class HistoryComponent implements OnInit {
  displayMode: string = 'default';
  multi = false;
  hideToggle = false;
  disabled = false;
  showPanel3 = true;
  expandedHeight: string;
  collapsedHeight: string;
  elements : Array<any>;

  constructor(private mds: MainDataService) {

    const v = this.mds.key;
    this.elements = JSON.parse(localStorage.getItem(v) || '[]');

  }

  ngOnInit() {
  }

}

这是子组件:

@Component({
  selector: 'app-history-item-tab-group',
  templateUrl: './tab-group-history.component.html',
  styleUrls: ['./tab-group-history.component.scss']
})


export class TabGroupHistoryComponent implements OnInit {

  constructor() {
  }

  ngOnInit() {
  }

}

这是孙子组件:

@Component({
  selector: 'app-history-generated-code',
  templateUrl: './history-generated-code.component.html',
  styleUrls: ['./history-generated-code.component.scss'],
  styles: [`
  mat-card { margin:2em; }
  `]
})


@Inject(ChromeDataService)
@Inject(MainDataService)

export class HistoryGeneratedCodeComponent implements OnInit {

  highlightedCode: string;
  googleCodo: string;
  rawCode = '';
  mySub: Subscription;
  codeTreeRoot = values.top.copy();
  currentNode = this.codeTreeRoot;
  rawGeneratedCode = '';
  formattedCode: string;


  constructor(private mds: MainDataService) {

    this.formattedCode = ' // (no code generated yet)';
    this.highlightedCode = Prism.highlight(this.formattedCode, Prism.languages.js);

  }

  ngOnInit() {


  }

  ngOnDestroy() {
    this.mySub.unsubscribe();
  }

  ngAfterContentInit() {
    Prism.highlightAll(true, function () {
      console.log('highlighted...');
    });
  }

  copyCodeToClipboard() {
    const textarea = document.createElement('textarea');
    textarea.setAttribute('type', 'hidden');
    textarea.textContent = this.formattedCode || this.rawCode;
    document.body.appendChild(textarea);
    // textarea.focus();
    textarea.select();
    document.execCommand('copy');
    textarea.parentNode.removeChild(textarea);
  }

  updateCode() {
    this.rawGeneratedCode = this.codeTreeRoot.generate();
    this.formattedCode = js_beautify(this.rawGeneratedCode, {
      brace_style: 'preserve-inline',
      max_preserve_newlines: 2
    });

    this.highlightedCode = Prism.highlight(this.formattedCode, Prism.languages.js);
  }


}

1 个答案:

答案 0 :(得分:0)

基本上我希望祖父母与孙子孙女交流,我希望有些孙子孙女能够相互沟通。

我发现这样做的最好方法是使用两个@Input电话将一个uuid传递给孙子孙女。从祖父母到孩子的@Input,然后从孩子到孙子@Input

然后在孙子们中,我使用那个uuid来查找某个类的唯一实例。该类的唯一实例存储在单例服务中的hashmap中。

不确定是否有更简单的方法可以做到这一点,虽然我猜这不是那么糟糕。

例如,这是单身人士服务:

//助手类

export class Foo {

}

//共享单件服务

@Injectable()
export class SharedSingletonService {

  foos : <{[key:string]:Foo}> = {}

  constructor(){

  }

  getInstanceOfFoo(uuid){
    if(this.foos[uuid]){
       return this.foos[uuid];
     }

    return this.foos[uuid] = new Foo();
  }

}