Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么我的*ngrx方法用于响应ngrx状态更改,而我的subscribe方法只响应一次_Javascript_Angular_Typescript_Ngrx - Fatal编程技术网

Javascript 为什么我的*ngrx方法用于响应ngrx状态更改,而我的subscribe方法只响应一次

Javascript 为什么我的*ngrx方法用于响应ngrx状态更改,而我的subscribe方法只响应一次,javascript,angular,typescript,ngrx,Javascript,Angular,Typescript,Ngrx,在我的应用程序中,我有一个ngrx存储,其中包含一组对象。在我的构造函数中,我选择数组并调用一个方法(onProductEntriesLoaded),该方法将变量设置为此数组。在html代码中有一个*ngFor循环,循环遍历这个变量并显示它们。设置变量的方法也会调用另一个计算和的方法。但是,每次在该状态下向该数组添加元素时,内容都会在*ngFor循环中正确显示。但是不调用将变量设置为数组的方法。它仅在初始化时调用。我认为每当状态改变时,订阅状态的应用程序的每个部分都会再次加载。即使它是一个构造函

在我的应用程序中,我有一个ngrx存储,其中包含一组对象。在我的构造函数中,我选择数组并调用一个方法(onProductEntriesLoaded),该方法将变量设置为此数组。在html代码中有一个*ngFor循环,循环遍历这个变量并显示它们。设置变量的方法也会调用另一个计算和的方法。但是,每次在该状态下向该数组添加元素时,内容都会在*ngFor循环中正确显示。但是不调用将变量设置为数组的方法。它仅在初始化时调用。我认为每当状态改变时,订阅状态的应用程序的每个部分都会再次加载。即使它是一个构造函数。然而,情况似乎并非如此。有人能给我解释一下这种行为吗

这是我的cart.component.html的一部分

 <div id="middle">
      <div class="entries">
        <div *ngFor="let entry of productEntries">
          <img
            *ngIf="!entry.product.image"
            src="../../../assets/img/esansBottles Kopie.png"
          />
          <img
            *ngIf="entry.product.image"
            src="../../../assets/img/{{ entry.product.image }}"
          />
          {{ entry.product.title }}
          {{ entry.variation.option }}
          {{ entry.variation.price }}
          {{ entry.amount }}
        </div>
      </div>
    </div>
    <div id="bottom">
      <div>Summe {{ sumOfCart }} €</div>
      <button>Zur Kasse</button>
    </div>

问题是由我的减速器功能引起的。在我的reducer中删除对addEntryToCart的函数调用并在reducer中实现功能后,问题得到了解决。我仍然不明白为什么调用函数会导致这个问题

我就是这样解决的:

export function shoppingCartReducer(
  state: ShoppinCartState = { CartIsOpen: false, Entries: [] },
  action: ShoppingCartAction
) {
  switch (action.type) {
    case "CART_TOGGLE":
      return {
        ...state,
        CartIsOpen: !state.CartIsOpen
      };
    case "CART_CLOSE":
      return {
        ...state,
        CartIsOpen: false
      };
    case "CART_ADD_ENTRY":
      let contains = state.Entries.findIndex(
        entry =>
          entry.product === action.payload.product &&
          entry.variation === action.payload.variation
      );
      if (contains === -1) {
        return {
          ...state,
          Entries: [...state.Entries.concat(action.payload)]
        };
      } else {
        return {
          ...state,
          Entries: [
            ...state.Entries.map(entry =>
              entry.product === action.payload.product &&
              entry.variation === action.payload.variation
                ? {
                    product: entry.product,
                    variation: entry.variation,
                    amount: entry.amount + action.payload.amount
                  }
                : entry
            )
          ]
        };
      }

    default:
      return state;
  }
}


看起来你正试图直接修改商店,这是不可能的。但是如果没有看到你的行动和减缩器,就很难猜出哪里出了问题
calculateSum
作为reducer用于更新状态的操作可能更好。看看这个,如果你还没有我添加了我的减速机功能。它是否会因为我在减速器中调用addEntryToCart方法而失败?

export function shoppingCartReducer(
  state: ShoppinCartState = { CartIsOpen: false, Entries: [] },
  action: ShoppingCartAction
) {
  switch (action.type) {
    case "CART_TOGGLE":
      return {
        ...state,
        CartIsOpen: !state.CartIsOpen
      };
    case "CART_CLOSE":
      return {
        ...state,
        CartIsOpen: false
      };
    case "CART_ADD_ENTRY":
      return {
        ...state,
        Entries: addEntryToCart(state.Entries, action.payload)
      };
    default:
      return state;
  }
}

function addEntryToCart(
  currentEntries: ShoppingCartEntry[],
  entry: ShoppingCartEntry
): ShoppingCartEntry[] {
  //if currentEntries is null return empty array
  if (currentEntries) {
    // if entry is null return currentEntries
    if (entry) {
      // check if currentEntries contains entry
      let index = currentEntries.findIndex(
        x => x.product === entry.product && x.variation === entry.variation
      );
      if (index === -1) {
        let newEntries = currentEntries;
        newEntries.push(entry);
        return newEntries;
      } else {
        currentEntries[index].amount += entry.amount;
        return currentEntries;
      }
    } else {
      return currentEntries;
    }
  } else {
    return [];
  }
}


export function shoppingCartReducer(
  state: ShoppinCartState = { CartIsOpen: false, Entries: [] },
  action: ShoppingCartAction
) {
  switch (action.type) {
    case "CART_TOGGLE":
      return {
        ...state,
        CartIsOpen: !state.CartIsOpen
      };
    case "CART_CLOSE":
      return {
        ...state,
        CartIsOpen: false
      };
    case "CART_ADD_ENTRY":
      let contains = state.Entries.findIndex(
        entry =>
          entry.product === action.payload.product &&
          entry.variation === action.payload.variation
      );
      if (contains === -1) {
        return {
          ...state,
          Entries: [...state.Entries.concat(action.payload)]
        };
      } else {
        return {
          ...state,
          Entries: [
            ...state.Entries.map(entry =>
              entry.product === action.payload.product &&
              entry.variation === action.payload.variation
                ? {
                    product: entry.product,
                    variation: entry.variation,
                    amount: entry.amount + action.payload.amount
                  }
                : entry
            )
          ]
        };
      }

    default:
      return state;
  }
}