你好,我创建了这个ngrx选择器
路径:导航 src app 商店navigation.selectors.ts
export const getNavigationState = createFeatureSelector<NavigationState>('navigation');
const getNavigation = createSelector(
getNavigationState,
(state) => {
return state.entities;
}
)
/**
* Get Arrays Of all Categories and submenu
*/
export const getFullMenu = createSelector(
getNavigation,
(state) => {
return state.menu
}
)
/**
* Get Arrays Of all Categories and submenu
*/
export const fullMenuCat = createSelector(
getFullMenu,
(categories) => {
categories.map((category) => {
return {title: category.title, url: category.url}
})
}
)
我不知道为什么,但是当我在我的组件中调用我的可观察对象时,我有这个问题:
ERROR TypeError: Cannot read properties of undefined (reading 'map')
这是我的数据从data.json
路径:src 数据 subnav.json
[
{
"id": "angular",
"title": "Angular stuff",
"url": "/angular",
"links": [
{
"name": "Components",
"url": "#"
},
{
"name": "Directives",
"url": "#"
},
{
"name": "Services",
"url": "#"
},
{
"name": "Pipe",
"url": "#"
},
{
"name": "Other",
"url": "#"
}
]
}
]
这些数据由ngrx effects使用
路径:导航 src app 商店navigation.effects.ts
read$ = createEffect(() => this.actions.pipe(
ofType(fromActions.Types.READ),
switchMap(() => {
return this.navigationService.getCategories().pipe(
map(data => {
return new fromActions.ReadSuccess(data);
})
)
})
))
最后这是导航界面
路径:导航 src app 商店navigation.models.ts
import { Category } from "@app/models/backend";
export interface Navigation {
isNavOpen: boolean,
currentCategory: string,
menu: Array<Category>,
lastUrlVisited: string
}
和Category接口
路径:src app 模型端 categorie index.ts
export interface Category {
id: string,
title: string,
url: string,
links: Array<Link>
}
export interface Link {
name: string,
url: string,
}
这是我组件的ts文件
路径:头 src app 组件header.component.ts
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { select, Store } from '@ngrx/store';
/**State */
import * as fromRoot from '@app/store';
import * as fromNavigation from '@app/store/navigation';
import { Observable } from 'rxjs';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class HeaderComponent implements OnInit {
fullMenuCat$: Observable<any>;
constructor(
private store: Store<fromRoot.State>,
) {
}
ngOnInit(): void {
this.store.dispatch(new fromNavigation.Read )
this.fullMenuCat$ = this.store.pipe(select(fromNavigation.fullMenuCat));
}
}
和我的html
中的fullMenuCat$ observable调用路径:头 src app 组件header.component.html
<nav *ngIf="fullMenuCat$ | async as fullMenuCat">
<ol class="header__categories__nav">
<li #link *ngFor="let menuCat of fullMenuCat" class="header__categories__navitem" (mouseover)="moveMarker($event)" (mouseout)="resetMarkerPos()" routerLinkActive="header__categories__navitem-active" >
<a class="categories-a" routerLink="{{menuCat.url}}">{{menuCat.title}}</a>
</li>
</ol>
</nav>
这个问题我已经研究了3天了,我不知道我需要做什么。为了更清楚,这里是我的项目的回购:https://github.com/orphen92/angular-demo.git你可以用"npm run start command">
来运行这个项目和一个实时urlhttps://orphen92.github.io/angular-demo/angular
我试图创建最具可扩展性的架构,所以我的代码在许多部分都是暴露的,我不能在这里链接所有的代码(总是为了清晰)。
我希望你能帮助我
您可能只需要为您的商店提供categories
的初始状态。或者在categories
为空时,使用可选的链接组合和空合并来为选择器提供默认值,如下所示:
export const fullMenuCat = createSelector(
getFullMenu,
(categories) => {
return categories?.map((category) => {
return {title: category.title, url: category.url}
}) ?? [];
}
)
因为你正在执行数据抓取,categories
总是将是空的第一次你的选择器试图读取它,这就是为什么你应该总是给你的状态一些初始值