带参数的自定义 Select()
Custom Select() with parameter
更新
从@NGXS v3.1 开始,他们终于在@Selector() 中引入了参数。
https://www.ngxs.io/concepts/select#lazy-selectors
来自文档的示例
首先,您定义@Select或“pandas”
@State<string[]>({
name: 'animals',
defaults: []
})
@Injectable()
export class ZooState {
@Selector()
static pandas(state: string[]) {
return (type: string) => {
return state.filter(s => s.indexOf('panda') > -1).filter(s => s.indexOf(type) > -1);
};
}
}
然后你只需在你的'.ts'文件中调用它
import { Store } from '@ngxs/store';
import { map } from 'rxjs/operators';
@Component({ ... })
export class ZooComponent {
babyPandas$: Observable<string[]>;
constructor(private store: Store) {
this.babyPandas$ = this.store
.select(ZooState.pandas)
.pipe(map(filterFn => filterFn('baby')));
}
}
* 从旧 Post *
我正在尝试创建自定义 @Select () 以便能够向下钻取特定的树并动态地 return 值。要么未定义,要么没有成功(正在执行)
user.component.ts
const location = 'new york'
@Select(state => UserState.getUserLocationSlots(state, location)) slots$;
user.state.ts
@Selector()
static getUserLocationSlots(state: UserStateModel, location: any) {
console.log(state);
console.log(location); // <-- expecting 'new york', but getting undefined
}
我认为在 ngxs v2 中无法将参数传递给 @Selector()
装饰函数。不过还是不错的。
存在此 feature request 的工单。
此外,我认为您没有正确使用@Selector()。我应该是这样的(因此,不能传递参数):
@Select(UserState.getUserLocationSlots) slots$
参考docs.
注意:我不是ngxs的专家...这只是基于我现在的理解。
这在 NGXS v2 和 v3 中是可以实现的。从我在动态选择器讨论中的评论中复制 here
We can achieve this at the moment using a pattern often used for redux
selectors...
The @Selector
decorator can be written so that it returns a function
with the desired parameter. This enables the desired dynamic selector
arguments as well as late resolution of the selected state. For
Example:
@State<UserStateModel>( ... )
export class UserState {
@Selector()
getFilteredUsersFn(userStateModel: UserStateModel) {
return (filter: string) =>
userStateModel.users.filter((user) => user.indexOf(filter) >= 0);
}
}
And then the component would contain:
@Component({...})
export class AppComponent {
@Select(UserState.getFilteredUsersFn)
filteredUsersFn$: Observable<(filter: string) => User[]>;
get currentFilteredUsers$() {
return this.filteredUsersFn$
.pipe(map(filterFn => filterFn('myFilter')));
}
}
要传递参数,您可以使用 select return 函数,它并不优雅,但它可以工作。
例如 select 语句如下所示:
@Selector()
static getItemByIdFn(state: { [id: number]: Entity }) {
return (id: number) => {
return state[id];
};
}
然后在组件中:
this.store.select(MyState.getItemByIdFn)
.pipe(map(mapByIdFn) => mayByIdFn(1)) // using the returned function
.subscribe(...);
注意地图,这是您将 id 传递给 returned 函数的地方。在这里你可以放置任何你想要的参数。
希望对您有所帮助:)!
您可以使用 @ngxs/store
中的 crateSelector
函数来实现此目的
在您的 .state.ts 文件中:
static getLocationSlots(location: string) {
return createSelector([UserState], (state: string[) => {
// logic for filtering your data
// eg.: state.filter(element => element == location)
})
}
In your .component.ts file:
@Select(UserState.getLocationSlots('new york')) slots$: Observable<any>
You can also check here for more details
更新
从@NGXS v3.1 开始,他们终于在@Selector() 中引入了参数。
https://www.ngxs.io/concepts/select#lazy-selectors
来自文档的示例
首先,您定义@Select或“pandas”
@State<string[]>({
name: 'animals',
defaults: []
})
@Injectable()
export class ZooState {
@Selector()
static pandas(state: string[]) {
return (type: string) => {
return state.filter(s => s.indexOf('panda') > -1).filter(s => s.indexOf(type) > -1);
};
}
}
然后你只需在你的'.ts'文件中调用它
import { Store } from '@ngxs/store';
import { map } from 'rxjs/operators';
@Component({ ... })
export class ZooComponent {
babyPandas$: Observable<string[]>;
constructor(private store: Store) {
this.babyPandas$ = this.store
.select(ZooState.pandas)
.pipe(map(filterFn => filterFn('baby')));
}
}
* 从旧 Post *
我正在尝试创建自定义 @Select () 以便能够向下钻取特定的树并动态地 return 值。要么未定义,要么没有成功(正在执行)
user.component.ts
const location = 'new york'
@Select(state => UserState.getUserLocationSlots(state, location)) slots$;
user.state.ts
@Selector()
static getUserLocationSlots(state: UserStateModel, location: any) {
console.log(state);
console.log(location); // <-- expecting 'new york', but getting undefined
}
我认为在 ngxs v2 中无法将参数传递给 @Selector()
装饰函数。不过还是不错的。
存在此 feature request 的工单。
此外,我认为您没有正确使用@Selector()。我应该是这样的(因此,不能传递参数):
@Select(UserState.getUserLocationSlots) slots$
参考docs.
注意:我不是ngxs的专家...这只是基于我现在的理解。
这在 NGXS v2 和 v3 中是可以实现的。从我在动态选择器讨论中的评论中复制 here
We can achieve this at the moment using a pattern often used for redux selectors...
The
@Selector
decorator can be written so that it returns a function with the desired parameter. This enables the desired dynamic selector arguments as well as late resolution of the selected state. For Example:@State<UserStateModel>( ... ) export class UserState { @Selector() getFilteredUsersFn(userStateModel: UserStateModel) { return (filter: string) => userStateModel.users.filter((user) => user.indexOf(filter) >= 0); } }
And then the component would contain:
@Component({...}) export class AppComponent { @Select(UserState.getFilteredUsersFn) filteredUsersFn$: Observable<(filter: string) => User[]>; get currentFilteredUsers$() { return this.filteredUsersFn$ .pipe(map(filterFn => filterFn('myFilter'))); } }
要传递参数,您可以使用 select return 函数,它并不优雅,但它可以工作。
例如 select 语句如下所示:
@Selector()
static getItemByIdFn(state: { [id: number]: Entity }) {
return (id: number) => {
return state[id];
};
}
然后在组件中:
this.store.select(MyState.getItemByIdFn)
.pipe(map(mapByIdFn) => mayByIdFn(1)) // using the returned function
.subscribe(...);
注意地图,这是您将 id 传递给 returned 函数的地方。在这里你可以放置任何你想要的参数。
希望对您有所帮助:)!
您可以使用 @ngxs/store
crateSelector
函数来实现此目的
在您的 .state.ts 文件中:
static getLocationSlots(location: string) {
return createSelector([UserState], (state: string[) => {
// logic for filtering your data
// eg.: state.filter(element => element == location)
})
}
In your .component.ts file:
@Select(UserState.getLocationSlots('new york')) slots$: Observable<any>
You can also check here for more details