2

更新

从@NGXS v3.1 开始,他们终于在@Selector() 中引入了参数。

https://www.ngxs.io/concepts/select#lazy-selectors

DOCS 中的示例

首先,您定义 @Selector “ 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')));
  }
}

*来自旧邮报*

我正在尝试创建一个自定义 @Select () 以便能够向下钻取特定树并动态返回值。获得未定义或未定义(执行)

用户.component.ts

const location = 'new york'
@Select(state => UserState.getUserLocationSlots(state, location)) slots$;

用户状态.ts

@Selector() 
static getUserLocationSlots(state: UserStateModel, location: any) {
  console.log(state);
  console.log(location); // <-- expecting 'new york', but getting undefined
}
4

4 回答 4

10

您可以通过使用crateSelector函数来实现这一点@ngxs/store

在您的 .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>

您也可以在此处查看更多详细信息

于 2019-04-22T14:38:28.510 回答
2

我认为不可能将参数传递给@Selector()ngxs v2 中的装饰函数。不过会很好。

此功能请求存在票证。

另外,我认为您没有正确使用 @Selector() 。我应该是这样的(因此,不能传递参数):

@Select(UserState.getUserLocationSlots) slots$

请参阅文档

注意:我不是 ngxs 方面的专家……这只是基于我现在所了解的。

于 2018-05-04T10:26:46.207 回答
2

这在 NGXS v2 和 v3 中是可以实现的。复制自我在此处讨论动态选择器时的评论

我们现在可以使用通常用于 redux 选择器的模式来实现这一点......

可以编写装饰器@Selector,使其返回带有所需参数的函数。这将启用所需的动态选择器参数以及所选状态的延迟解析。例如:

@State<UserStateModel>( ... ) 
export class UserState {   
  @Selector()  
  getFilteredUsersFn(userStateModel: UserStateModel) {
    return (filter: string) => 
      userStateModel.users.filter((user) => user.indexOf(filter) >= 0);
  }
} 

然后该组件将包含:

@Component({...}) 
export class AppComponent {  
  @Select(UserState.getFilteredUsersFn) 
  filteredUsersFn$: Observable<(filter: string) => User[]>;

  get currentFilteredUsers$() {
    return this.filteredUsersFn$
      .pipe(map(filterFn => filterFn('myFilter')));   
  } 
} 
于 2018-05-21T07:01:09.963 回答
1

要传递参数,您可以让 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 传递给返回函数的地方。在这里您可以放置​​您想要的任何参数。

希望这可以帮助 :)!

于 2018-07-09T07:28:28.530 回答