Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/445.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 将Object.assign()与其他操作结合使用时,Ngrx观测值不会对状态存储更改作出反应_Javascript_Angular_Redux_Ngrx - Fatal编程技术网

Javascript 将Object.assign()与其他操作结合使用时,Ngrx观测值不会对状态存储更改作出反应

Javascript 将Object.assign()与其他操作结合使用时,Ngrx观测值不会对状态存储更改作出反应,javascript,angular,redux,ngrx,Javascript,Angular,Redux,Ngrx,我很难理解为什么第一个样本似乎可以正常工作,但第二个样本很难启动观察者 // Working reducer return Object.assign({}, state, { expanded: Object.assign({}, state.expanded, { clients: !state.expanded.clients }) }); // Faulty reducer - Devtools indicates a change but the observables /

我很难理解为什么第一个样本似乎可以正常工作,但第二个样本很难启动观察者

// Working reducer
return Object.assign({}, state, {
    expanded: Object.assign({}, state.expanded, { clients: !state.expanded.clients })
});

// Faulty reducer - Devtools indicates a change but the observables 
// seem to not respond and pass on the information down the line
newState = Object.assign({}, state);
newState.expanded.clients = !state.expanded.clients;


// Selectors
import {createSelector} from 'reselect';
export const SIDEBAR = (state: AppState) => state.sidebar;
export const SIDEBAR_UI = createSelector<AppState, SidebarUIState, SidebarState>(
    SIDEBAR,
    (state: SidebarState) => state.ui
);

// Sidebar service
public getSidebarUIExpandedObservable(): Observable<SidebarUIExpandedState> {
    debug('Get sidebar UI expanded observable');
    return this._store.select(SIDEBAR_UI_EXPANDED);
}
//工作减速器
返回Object.assign({},state{
扩展:Object.assign({},state.expanded,{clients:!state.expanded.clients})
});
//减速器故障-Devtools表示发生了变化,但可观察到
//似乎没有回应,也没有把信息传递下去
newState=Object.assign({},state);
newState.expanded.clients=!国家客户;
//选择器
从“重新选择”导入{createSelector};
导出常量边栏=(状态:AppState)=>state.SIDEBAR;
导出常量边栏_UI=createSelector(
侧边栏,
(state:SidebarState)=>state.ui
);
//边栏服务
public getSidebarUIExpandedObservable():可观察{
调试('Get sidebar UI expanded observable');
返回此。\u存储。选择(侧栏\u UI\u展开);
}

还原程序需要使用不可变对象的纯函数。 因此,您不能改变newState对象,但必须创建一个在创建时具有明确新状态的新对象

第一个示例符合不可变原则,因为Object.assign将第三个参数中对象的匹配属性复制到第二个参数中的对象副本,然后再将其分配给目标对象(第一个参数)。因此,原始状态保持不变,并且在目标对象中获得新状态。 换句话说,内存中的object.assign没有更改任何原始对象状态,返回值将提供一个随时可用(无需进一步更改)的新状态对象。 有关Object.assign()的详细信息:


在第二种情况下,首先创建了一个新对象(不变性仍然有效),随后,通过分配布尔值来改变状态,因此不变性原则被打破,并且还原程序通常不接受这一点

减速器中有以下部件:

newState = Object.assign({}, state);
newState.expanded.clients = !state.expanded.clients;
state.expanded
的内容正在发生变化

newState.expanded
state.expanded
引用同一对象,并且该对象的
client
属性正在发生变化。查看展开的的代码将看到对象引用未更改,并将假定内容也未更改,但您通过切换其客户端的属性的值对其进行了变异。

而不是执行以下操作:

newState = Object.assign({}, state);
newState.expanded.clients = !state.expanded.clients;

技巧: 当您使用Typescript>=2.1.4时,您就可以这样做了

return {
  ...state,
  {
    expanded: {
      ...state.expanded,
      {
        clients: !state.expanded.clients
      }
    }
  }
};

谢谢你们!我能接受这三个答案吗D我将等待公众的更多投票,并选择投票最多的一家使用spread operator的公司。看起来脸红。实际上我使用的是2.1.5。所以我将忙于重构。谢谢
return {
  ...state,
  {
    expanded: {
      ...state.expanded,
      {
        clients: !state.expanded.clients
      }
    }
  }
};