使用带有实体的新 NGRX 信号存储,我无法访问 TypeScript 文件中的实体信号属性

问题描述 投票:0回答:1

我开始使用新的 NGRX Signal Store 中的“withEntities”。它效果很好,几乎正是我正在寻找的东西。
在我的组件中,我可以让它正常工作并访问模板 HTML 文件中的“实体”。 但是,在组件的打字稿文件“.ts”中,我无法直接访问数据存储,也不知道如何操作。请问有人可以帮忙吗?

我有以下代码:

这是 src pp\models uilder-expirations.ts 中的模型

export type BuilderExpirations = {
    id: string;
    CardNumber: number | null;
    DTE: number | null;
    DTE_Min: number | null;
    DTE_Max: number | null;
    Expiration_Name: string | null;
}

注意,在定义的类型“BuilderExpirations”中,我根据使用“withEntities”的文档中的要求添加了“id”字段,并且它按预期工作。

这是商店的代码。 src pp\Stores uilder.store.ts

export const BuilderExpirationStore = signalStore(
    { providedIn: 'root' },
    withEntities<BuilderExpirations>(),
    withMethods(
        (store, builderService = inject(BuilderService)) => ({
            async loadAll() {
                const expirations = await builderService.getExpirations();
                patchState(store, addEntities(expirations));
            },
            async insertOrUpdate(id: string, CardNumber: number | null, DTE: number | null, DTE_Min: number | null, DTE_Max: number | null, Expiration_Name: string | null) {
                await builderService.insertOrUpdateExpiration(id, CardNumber, DTE, DTE_Min, DTE_Max, Expiration_Name);
                patchState(store, setEntity({ id: id, CardNumber: CardNumber, DTE: DTE, DTE_Min: DTE_Min, DTE_Max: DTE_Max, Expiration_Name: Expiration_Name }));
            },
            async deleteOne(id: number | null) {
                let idString = id!.toString();
                await builderService.deleteExpiration(idString);
                patchState(store, removeEntity(idString));
            },
            async deleteAll() {
                await builderService.deleteAllExpirations();
                patchState(store, removeAllEntities());
            },
        })
    )
);

然后这是 typescript 文件 src pp\BuilderComponents xpiration-info xpiration-info.component.ts 中的组件

@Component({
  selector: 'app-expiration-info',
  standalone: true,
  imports: [ExpirationCardComponent, FormsModule, JsonPipe, MatButtonModule, MatFormFieldModule, MatInputModule, ReactiveFormsModule],
  templateUrl: './expiration-info.component.html',
  styleUrl: './expiration-info.component.scss'
})
export class ExpirationInfoComponent implements OnInit {
  
  expirationsList = [0];
  expiryCount = 0;
  builderExpirationStore = inject(BuilderExpirationStore);

  ngOnInit(): void {
    this.loadExpirations()
      .then(() => console.log("Expirations loaded"));
  }

  loadExpirations() {
    // Notice how I am able get the count of records in the data store... this works
    this.expiryCount = this.builderExpirationStore.entities().length;  // <--this works
    if (this.expiryCount === 0) {
      this.expirationsList = [1];
    }
    else {
      let card = 0;
      this.expirationsList = [];
      
      // But then in this for loop, I'm not able to access any 
      // of the attributes from "this.builderExpirationStore.entities()"
      // How can I get this to work?
      for (let exp in this.builderExpirationStore.entities())
      {
        // card = exp.CardNumber;  // this doesn't work... what syntax do I use???
        // card = exp.CardNumber();  // this doesn't work... what syntax do I use???
        // card = exp().CardNumber;  // this doesn't work... what syntax do I use???
        this.expirationsList.push(card);
      }
    }

  }
  
}

所以上面的代码是我遇到问题的地方,无法使用组件的 TypeScript 文件中的“withEntities”访问 NGRX Signal Store 中的属性。

有趣的是,这是模板文件或 HTML 文件,我可以在其中使一切正常工作。 src pp\BuilderComponents xpiration-info xpiration-info.component.html

<form class="expirations-form" >   
    <div class="exp-card-layout">
        @if (expiryCount === 0) {
            @for (card of expirationsList; track $index) {
                <app-expiration-card class="exp-card-item" [cardNumber]="card"></app-expiration-card>
            }
        }
        @else {
            <!-- Accessing the store data works as expected...nothing wrong here... -->
            @for (card of builderExpirationStore.entities(); track $index) {
                <app-expiration-card class="exp-card-item" [cardNumber]="card.CardNumber">{{ card.CardNumber }}</app-expiration-card>
            }
        }
        
    </div>
    <br>
    <br>
    
    <!-- For testing purposes output the "builderStore.expirations()" store data using JSON... -->
    <!-- Accessing the store data works as expected...nothing wrong here... -->
    <div class="expirations-output">{{ builderExpirationStore.entities().length }}</div>
    <div class="expirations-output">{{ builderExpirationStore.entities() | json}}</div>
</form>

所以上面的 HTML 代码按预期工作,我可以很好地访问“CardNumber”。 但在打字稿文件“expiration-info.component.ts”中,我无法访问“CardNumber”。请有人告诉我需要使用什么语法来使用“withEntities”访问 NGRX 信号存储中的“CardNumber”?预先感谢。

angular typescript ngrx ngrx-store
1个回答
0
投票

问题出现在

for
循环内,这应该是:

//            👇 should use `of` instead of `in`
  for (let exp of this.builderExpirationStore.entities())
      {
        // 👇 then you can do 
        card = exp.CardNumber;  // this doesn't work... what syntax do I use???
        // card = exp.CardNumber();  // this doesn't work... what syntax do I use???
        // card = exp().CardNumber;  // this doesn't work... what syntax do I use???
        this.expirationsList.push(card);
      }
© www.soinside.com 2019 - 2024. All rights reserved.