Akita+Single State Stream 모드의 원활한 Observable
19192 단어 AngularTypeScriptRxjsakitatech
개시하다
이 글은 lacolaco가 제창한Single State Stream 모드과 Anglar 상태 관리 라이브러리Akita를 조합해 Observable를 시원하게 만들었다는 기사다.
특히 아키타가 로딩 주변에서 다루는 최선의 실천 방법을 권장하지 않고 있다는 점에 주목하고 해설하겠다.
※ 아키타에 대해서는 자세히 설명하지 않습니다.
Akita의 selectLoading 과제
Akita의 loading은 매우 강력하다.서비스와 조회에서 구성 요소가 아닌 상점이 업데이트되고 있는지 판단할 수 있습니다.
class UserService {
constructor(
userStore: UserStore,
userHttpService: UserHttpService,
)
fetchUsers(): Promise<void> {
this.userStore.setLoading(true); // 読み込みを始めるためtrueに
return this.userHttpService.fetchUsers()
.pipe(
tap(users => userStore.set(users)),
tap(() => this.userStore.setLoading(false)), // 読み込み終了
mapTo(undefined)
);
}
}
서비스 측면은 매우 간단할 것이다.이렇게 사용자를 찾았을 때 상점에서 읽는 중입니다.그러나 구성 요소의 경우 아래와 같이 구독하는 Observable이 늘어나 지루해졌다.
class UserComponent implements OnDestroy {
users: User[];
isLoading: boolean;
onDestroy$ = new EventEmitter();
constructor(
userQuery: UserQuery,
userService: UserService,
) {
this.userQuery
.selectAll()
.pipe(takeUntil(this.onDestroy$))
.subscribe(users => {
this.users = users;
});
this.userQuery
.selectLoading()
.pipe(takeUntil(this.onDestroy$))
.subscribe(isLoading => {
this.isLoading = isLoading
});
this.userService.fetchUsers();
}
ngOnDestroy(): void {
this.onDestroy$.next();
}
}
또한 async 파이프 모드로 쓰면 다음과 같다.Observable boolean의 isLoading 달러는 async 파이프로 해결할 수 없습니다.
(=isLoading 자체가 가짜인 경우,ngIf는 가짜평가로 이전의 DOM에 도달할 수 없음)
@Component({
templateUrl: '
<ng-container *ngIf="isLoading$ | async as isLoading">
<ng-container *ngIf="users$ | async as users">
</ng-container>
</ng-container>
',
})
class UserComponent implements OnDestroy {
users$: Observable<User[]>;
isLoading$: Observable<boolean>;
constructor(
userQuery: UserQuery,
userService: UserService,
) {
this.users$ = this.userQuery.selectAll();
this.isLoading$ = this.userQuery.selectLoading();
this.userService.fetchUsers();
}
}
Single State Stream 모드를 통한 해결
위에서 말한 바와 같이 Akita loading을 사용하는 데는 두 가지 과제가 있다.
자잘한 데서 참고 기사를 읽을 수 있었으면 좋겠어요.
Single State Stream에서는 Observable 관리 상태를 구성 요소로 통합합니다.
Observable 병합 시 사용
combineLatest
.type UserComponentState = {
users: User[];
isLoading: boolean
};
@Component({
templateUrl: '
<ng-container *ngIf="state$ | async state">
<ng-container *ngIf="!state.isLoading">
<ul>
<li *ngFor="let user of state.users">
{{user.name}}
</li>
</ul>
</ng-container>
<ng-container *ngIf="state.isLoading">
<span>読込中</span>
</ng-container>
</ng-container>
',
})
class UserComponent implements OnDestroy {
state$: Observable<UserComponentState>;
constructor(
userQuery: UserQuery,
userService: UserService,
) {
this.state$ = combineLatest([
this.userQuery.selectAll(),
this.userQuery.selectLoading()
]).pipe(
map(value => ({
users: value[0],
isLoading: value[1] // 少し不思議な書き方ですが、型がついているので安心です。
}));
);
this.userService.fetchUsers();
}
잘 나오네요.총괄해 보면 다음과 같은 효과가 있다고 볼 수 있다.읽어주셔서 감사합니다!
Reference
이 문제에 관하여(Akita+Single State Stream 모드의 원활한 Observable), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/yuitosato/articles/3f579b26fb8e3a27914d텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)