You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现组件渲染时服务outerCounter仅递增一次及计数器差异化需求

共享组件编号与私有计数器实现方案

一、全局共享组件编号服务

创建单例服务,维护全局递增的组件编号,确保每个组件仅在首次初始化时获取唯一且固定的编号,销毁重建后不再触发编号递增:

// counter.service.ts
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root' // 单例模式,全局共享状态
})
export class CounterService {
  private globalOuterCounter = 0;
  // 存储组件标识与对应编号的映射,避免重复递增
  private componentNumberMap = new Map<string, number>();

  /**
   * 获取组件对应的固定编号
   * @param componentId 组件唯一标识(自定义字符串即可)
   */
  getComponentOuterNumber(componentId: string): number {
    if (!this.componentNumberMap.has(componentId)) {
      this.globalOuterCounter++;
      this.componentNumberMap.set(componentId, this.globalOuterCounter);
    }
    return this.componentNumberMap.get(componentId)!;
  }
}

二、组件私有计数器实现

每个组件独立维护自己的innerCounter,初始值为1,提供递增方法,同时在初始化时从服务获取固定的组件编号:

第一个组件示例

// first.component.ts
import { Component } from '@angular/core';
import { CounterService } from './counter.service';

@Component({
  selector: 'app-first',
  template: `
    <div class="counter-display">{{ outerNumber }}.{{ innerCounter }}</div>
    <button (click)="incrementInnerCounter()">递增内部计数器</button>
  `,
  styles: [`.counter-display { margin: 10px 0; } button { padding: 6px 12px; }`]
})
export class FirstComponent {
  innerCounter = 1;
  outerNumber: number;
  // 组件唯一标识,确保销毁重建后能匹配到之前的编号
  private readonly componentId = 'first-component';

  constructor(private counterService: CounterService) {
    this.outerNumber = this.counterService.getComponentOuterNumber(this.componentId);
  }

  incrementInnerCounter(): void {
    this.innerCounter++;
  }
}

第二个组件示例

// second.component.ts
import { Component } from '@angular/core';
import { CounterService } from './counter.service';

@Component({
  selector: 'app-second',
  template: `
    <div class="counter-display">{{ outerNumber }}.{{ innerCounter }}</div>
    <button (click)="incrementInnerCounter()">递增内部计数器</button>
  `,
  styles: [`.counter-display { margin: 10px 0; } button { padding: 6px 12px; }`]
})
export class SecondComponent {
  innerCounter = 1;
  outerNumber: number;
  private readonly componentId = 'second-component';

  constructor(private counterService: CounterService) {
    this.outerNumber = this.counterService.getComponentOuterNumber(this.componentId);
  }

  incrementInnerCounter(): void {
    this.innerCounter++;
  }
}

第三个组件示例

// third.component.ts
import { Component } from '@angular/core';
import { CounterService } from './counter.service';

@Component({
  selector: 'app-third',
  template: `
    <div class="counter-display">{{ outerNumber }}.{{ innerCounter }}</div>
    <button (click)="incrementInnerCounter()">递增内部计数器</button>
  `,
  styles: [`.counter-display { margin: 10px 0; } button { padding: 6px 12px; }`]
})
export class ThirdComponent {
  innerCounter = 1;
  outerNumber: number;
  private readonly componentId = 'third-component';

  constructor(private counterService: CounterService) {
    this.outerNumber = this.counterService.getComponentOuterNumber(this.componentId);
  }

  incrementInnerCounter(): void {
    this.innerCounter++;
  }
}

三、效果说明

  • 首次加载三个组件时,服务会依次为每个组件分配唯一编号,显示内容分别为1.1、2.1、3.1。
  • 点击任意组件的递增按钮,仅该组件的innerCounter会递增,显示如1.2、2.2等,其他组件不受影响。
  • 组件销毁重建后,会从服务中获取之前分配的固定编号,不会触发全局计数器再次递增。

内容的提问来源于stack exchange,提问作者M. Al Jumaily

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 04:25:12