简体   繁体   English

Angular 8 将 ngrx 状态绑定到组件

[英]Angular 8 bind ngrx state to component

I am new to Angular and I want to bind some Classnames in my HTML to some values in my states.我是 Angular 的新手,我想将 HTML 中的一些类名绑定到我所在州的一些值。 At first I had only one state, which was only some boolean value and everything worked fine.起初我只有一个状态,它只是一些布尔值,一切正常。 Now I changed the state to an object, so that I can save more information in it.现在我将状态更改为一个对象,以便我可以在其中保存更多信息。 Although I am using more or less the same approach as before but the classname doesn't change.虽然我使用的方法或多或少与以前相同,但类名没有改变。 The state does change.状态确实发生了变化。 Can someone please tell me what my mistake is and if there is another more appropriate way to do the things I am trying to do please tell me that also.有人可以告诉我我的错误是什么,如果有另一种更合适的方法来做我想做的事情,也请告诉我。

The angular version is 8.2.14.角度版本是 8.2.14。

This is my code:这是我的代码:

reducer.ts:减速器.ts:


export type ShoppinCartState = {
  CartIsOpen: boolean;
};

export type HamburgerState = {
  MenuIsOpen: boolean;
};

export function hamburgerReducer(
  state: HamburgerState = { MenuIsOpen: false },
  action: Action
) {
  switch (action.type) {
    case "HAMBURGER.TOGGLE":
      console.log("HAMBURGER.Toggle called " + state.MenuIsOpen);
      return {
        ...state,
        MenuIsOpen: !state.MenuIsOpen
      };
    case "HAMBURGER.CLOSE":
      return {
        ...state,
        MenuIsOpen: false
      };
    case "HAMBURGER.OPEN":
      return {
        ...state,
        MenuIsOpen: true
      };
    default:
      return state;
  }
}

export function shoppingCartReducer(
  state: ShoppinCartState = { CartIsOpen: false },
  action: Action
) {
  switch (action.type) {
    case "CART.TOGGLE":
      console.log("Tooggle cart called " + state.CartIsOpen);
      return {
        ...state,
        CartIsOpen: !state.CartIsOpen
      };
    default:
      return state;
  }
}

This is my Component.这是我的组件。 When the user clicks on the Hamburger Icon one action is dispatched which changes the state.当用户点击汉堡图标时,会发送一个改变状态的动作。 There is also another part which is binded to the state.还有另一部分与国家有关。 When the value is true, the classname should be "visible".当值为真时,类名应该是“可见的”。

<app-hamburger-icon (click)="onHamburgerIconClick()"></app-hamburger-icon>
  <div id="Logo"><a (click)="onLinkClick()" routerLink="/">E99-EsAns</a></div>
  <ul [ngClass]="{ visible: hamburgerClicked$ | async }">

And that's the component.ts file这就是 component.ts 文件

import { Store } from "@ngrx/store";
import { Observable } from "rxjs";
import { HamburgerState } from "src/app/reducer";

@Component({
  selector: "app-navigationbar",
  templateUrl: "./navigationbar.component.html",
  styleUrls: ["./navigationbar.component.css"]
})
export class NavigationbarComponent implements OnInit {
  hamburgerClicked$: Observable<boolean>;

  constructor(private store: Store<HamburgerState>) {
    this.hamburgerClicked$ = this.store.select("MenuIsOpen");
  }

  ngOnInit() {}

  onHamburgerIconClick() {
    console.log(this.hamburgerClicked$);
    this.store.dispatch({ type: "HAMBURGER.TOGGLE" });
  }

  onLinkClick() {
    this.store.dispatch({ type: "HAMBURGER.CLOSE" });
  }

  onShoppingCartIconClicked() {
    this.store.dispatch({ type: "CART.TOGGLE" });
  }
}

Some snippet of my app.module.ts我的 app.module.ts 的一些片段

import { hamburgerReducer, shoppingCartReducer } from "./reducer";
...
...
...
imports: [
    BrowserModule,
    BrowserAnimationsModule,
    AppRoutingModule,
    HttpClientModule,
    StoreModule.forRoot({
      hamburgerReducer: hamburgerReducer,
      shoppingCartReducer: shoppingCartReducer
    })
  ],

When you inject the Store into a component you operate on the structure of the global state.当您将Store注入组件时,您对全局状态的结构进行操作。 So the select has to 'select' into this structure to access the correct object.所以选择必须“选择”到这个结构中才能访问正确的对象。

Only the reducer functions get handed a slice of this global state.只有reducer 函数得到了这个全局状态的一部分。 We can see that most likely in app.module.ts where you define your store:我们可以在app.module.ts中看到您定义商店的最有可能的app.module.ts

    StoreModule.forRoot({
      hamburgerReducer: hamburgerReducer,
      shoppingCartReducer: shoppingCartReducer
    })

Best practice is to create a interface State that describes your store structure:最佳实践是创建一个接口State来描述您的商店结构:

export interface State {
   hamburgerReducer: HamburgerState;
   shoppingCartReducer: ShoppingCartState;
}

and then use this interface when injecting the store:然后在注入 store 时使用这个接口:

constructor(private store: Store<State>)

then you can select the hamburger menu-state via:然后您可以通过以下方式选择汉堡菜单状态:

this.store.select(state => state.hamburgerReducer.MenuIsOpen)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM