angular 秋田犬非常奇怪的行为

angular akita very strange behavior

这里我从存储中获取数据

sendRequest() {
    this.userservise.getAllUsers(...)
    console.log("bedore")
    this.query.selectAll().subscribe(users => {
        console.log("inside")
        this.users = users
    })
    console.log("after")
}

这里我写在存储中

  getAllUsers(...) {
    var url = ...
    return this.http.get<User[]>(url, { withCredentials: true }).subscribe(u => {
      this.store.set(u)
    });
  }

奇怪的是“insede”函数触发了很多次,每个新请求都会触发一次。看 scan

对数据库的查询总是发送一个,这是应该的。 另外,如果你排除秋田犬,一切都会好起来的。

  sendRequest() {
    this.userservise.getAllUsers(...).subscribe(users => {
        this.users = users
      })
  }

  getAllUsers(...): Observable<User[]> {
    var url = ...
    return this.http.get<User[]>(url, { withCredentials: true })
  }

商店:

import { Injectable } from '@angular/core';
import { EntityState, EntityStore, StoreConfig } from '@datorama/akita';
import { User } from '../user';

export interface TodosState extends EntityState<User, number> { }

@Injectable({
  providedIn: 'root'
})
@StoreConfig({ name: 'todos' })
export class TodosStore extends EntityStore<TodosState> {
  constructor() {
    super() ;
  }
}

查询:

import { Injectable } from "@angular/core";
import { QueryEntity } from "@datorama/akita";
import { TodosState, TodosStore } from "./store";
    
@Injectable({
    providedIn: 'root'
})
export class TodosQuery extends QueryEntity<TodosState> {
    constructor(protected override store: TodosStore) {
        super(store);
    }
}

可能是什么问题?

我认为您的操作存在一些问题。我认为您正在以某种奇怪的方式使用 RxJS observable,这可能会导致这种情况。在查看完整代码之前,我无法判断哪里出了问题,但也许我的示例可以帮助您理解正确的做法。

在您的服务中,您应该有一个 getUsers 方法,如下所示:

public getUsers(): Observable<User[]> {
    var url = "";
    return this.http.get<User[]>(url).pipe(tap((data) => {
        this._store.add(data);
    }));
}

然后在您的 component.ts 文件中,执行以下操作:

public readonly todos$ = this._query.selectAll();

最后,在HTML模板中,您可以按如下方式使用它:

<ol>
  <li *ngFor="let user of todos$ | async">
    {{ user.name }}
  </li>
</ol>

如果您想访问 User[] 的属性,您可以在 HTML:

中执行以下操作
<p *ngIf="todos$ | async as todos">
    You have: {{ todos.length }}. <br />
    JSON: {{ todos | json }}
</p>

您还可以在 Stackblitz 上看到上面的 运行 示例。

更新:

我想我也意识到,你做错了什么。以下是您在 OP 中分享的示例。

sendRequest() {
    this.userservise.getAllUsers(...)
    console.log("bedore")
    this.query.selectAll().subscribe(users => {
        console.log("inside")
        this.users = users
    })
    console.log("after")
}

你每次比上次多进入一次的原因是因为你每次都订阅了一个新的可观察对象而不丢弃旧的。您的问题可以按如下方式解决,但仍然不是推荐的方法。

sendRequest() {
    this.userservise.getAllUsers(...)
    console.log("bedore")
    this.query.selectAll()
      .pipe(first())
      .subscribe(users => {
        console.log("inside")
        this.users = users
    })
    console.log("after")
}