如何在 Immutable.Map({}) 内更改 ImmutableList({}) 中项目的 属性
How to change property of item in ImmutableList({}) inside Immutable.Map({})
如何更改 Immutable.Map({})
中 ImmutableList({})
中项目的 属性?
我有:
const initialState = Immutable.Map({
width: window.board.width,
height: window.board.height,
lines: Immutable.List([
Immutable.Map({id: 1, active: false, name: 'Some name'}),
Immutable.Map({id: 2, active: false, name: 'Sad name'}),
Immutable.Map({id: 3, active: true, name: 'Cool name'})
])
});
假设我想在列表中设置 id
1 的项目。然后将其 属性 active 更改为 true。我还想将列表中所有其他项目的 属性 active 设置为 false。
我该怎么做?提前致谢。
编辑(最终解决方案):
export function activateLine(lineId) {
return function (dispatch, getState) {
const updatedLines = getState().board.update('lines', Immutable.List(),
(oldList) => oldList.map((listItem) => {
return listItem.set("active", (listItem.get("id") === lineId));
})).get('lines');
return dispatch({
type: types.ACTIVATE_LINE,
payload: updatedLines
});
};
}
接下来的内容应该可行,但是,正如有人所说...我认为完整更新可能会更好...
const initialState = Immutable.Map({
lines: Immutable.List([
Immutable.Map({id: 1, active: false, name: 'Some name'}),
Immutable.Map({id: 2, active: false, name: 'Sad name'}),
Immutable.Map({id: 3, active: true, name: 'Cool name'})
])
});
let lines = initialState.get('lines');
let id = 1; // what you want update...
let updater = item => {
let updated = item.set('name', "Giuseppe");
return updated;
};
let index = lines.findIndex((i) => i.get("id") === id);
let result = lines.update(index, updater);
initialState.set("lines", result);
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.js"></script>
您可以像这样遍历不可变对象(请注意,尽管我强烈建议您将整个对象设置为不可变对象)。您可以通过 just 使用不可变本身来减少代码行并使其更优雅 -
const changeImmutableObject = initialState.update('lines', Immutable.List(),
(oldList) => oldList.map((listItem) => {
if(listItem.get("id") === 1) {
return listItem.set("active", true);
} else {
return listItem.set("active", false);
}
})
)
查看工作 fiddle - https://jsfiddle.net/o04btr3j/214/
这会更新对象内的 list
键(如果它由于某种原因不存在,则默认为不可变列表),然后映射到属性上。如果它的 id 为 1,它会将 active 设置为 true,否则它会将 active 设置为 false。
您也可以只 initialState.toJS()
您的不可变对象并在纯 js 中执行您的逻辑,或者执行和 immutableobject.get('property')
并修改然后将其设置回您的对象,但是我建议您只是使用不可变的内置方法,因为它 代码少得多。
此外,如果我没记错的话,你可以这样做:
const initialState = Immutable.fromJS({
width: window.board.width,
height: window.board.height,
lines:[
{id: 1, active: false, name: 'Some name'},
{id: 2, active: false, name: 'Sad name'},
{id: 3, active: true, name: 'Cool name'}
]
});
你可以 immutable.fromJS() 一个对象,把它变成一个不可变的对象。所有不可变对象都应该有一个 .toJS 方法来将它们变回常规 javascript objects/lists/whatever.
我在 link to solution on jsbin.com
上创建了轻巧的示例
const initialState = Immutable.Map({
lines: Immutable.List([
Immutable.Map({id: 1, active: false, name: 'Some name'}),
Immutable.Map({id: 2, active: false, name: 'Sad name'}),
Immutable.Map({id: 3, active: true, name: 'Cool name'})
])
});
console.log('initialState', initialState.toJS())
// update lines, map over items and set active to false
const stateLinesAllNotActive = initialState.updateIn(
['lines'],
items => items.map((item) => item.set('active', false))
)
console.log('stateLinesAllNotActive', stateLinesAllNotActive.toJS())
// lines and key for item with id === 1, then set active to this item
const stateFirstActive = stateLinesAllNotActive.updateIn(
[
'lines',
stateLinesAllNotActive.get('lines').findIndex((item) => (item.get("id") === 1))
],
item => item.set("active", true)
)
console.log('stateFirstActive', stateFirstActive.toJS())
如何更改 Immutable.Map({})
中 ImmutableList({})
中项目的 属性?
我有:
const initialState = Immutable.Map({
width: window.board.width,
height: window.board.height,
lines: Immutable.List([
Immutable.Map({id: 1, active: false, name: 'Some name'}),
Immutable.Map({id: 2, active: false, name: 'Sad name'}),
Immutable.Map({id: 3, active: true, name: 'Cool name'})
])
});
假设我想在列表中设置 id
1 的项目。然后将其 属性 active 更改为 true。我还想将列表中所有其他项目的 属性 active 设置为 false。
我该怎么做?提前致谢。
编辑(最终解决方案):
export function activateLine(lineId) {
return function (dispatch, getState) {
const updatedLines = getState().board.update('lines', Immutable.List(),
(oldList) => oldList.map((listItem) => {
return listItem.set("active", (listItem.get("id") === lineId));
})).get('lines');
return dispatch({
type: types.ACTIVATE_LINE,
payload: updatedLines
});
};
}
接下来的内容应该可行,但是,正如有人所说...我认为完整更新可能会更好...
const initialState = Immutable.Map({
lines: Immutable.List([
Immutable.Map({id: 1, active: false, name: 'Some name'}),
Immutable.Map({id: 2, active: false, name: 'Sad name'}),
Immutable.Map({id: 3, active: true, name: 'Cool name'})
])
});
let lines = initialState.get('lines');
let id = 1; // what you want update...
let updater = item => {
let updated = item.set('name', "Giuseppe");
return updated;
};
let index = lines.findIndex((i) => i.get("id") === id);
let result = lines.update(index, updater);
initialState.set("lines", result);
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.js"></script>
您可以像这样遍历不可变对象(请注意,尽管我强烈建议您将整个对象设置为不可变对象)。您可以通过 just 使用不可变本身来减少代码行并使其更优雅 -
const changeImmutableObject = initialState.update('lines', Immutable.List(),
(oldList) => oldList.map((listItem) => {
if(listItem.get("id") === 1) {
return listItem.set("active", true);
} else {
return listItem.set("active", false);
}
})
)
查看工作 fiddle - https://jsfiddle.net/o04btr3j/214/
这会更新对象内的 list
键(如果它由于某种原因不存在,则默认为不可变列表),然后映射到属性上。如果它的 id 为 1,它会将 active 设置为 true,否则它会将 active 设置为 false。
您也可以只 initialState.toJS()
您的不可变对象并在纯 js 中执行您的逻辑,或者执行和 immutableobject.get('property')
并修改然后将其设置回您的对象,但是我建议您只是使用不可变的内置方法,因为它 代码少得多。
此外,如果我没记错的话,你可以这样做:
const initialState = Immutable.fromJS({
width: window.board.width,
height: window.board.height,
lines:[
{id: 1, active: false, name: 'Some name'},
{id: 2, active: false, name: 'Sad name'},
{id: 3, active: true, name: 'Cool name'}
]
});
你可以 immutable.fromJS() 一个对象,把它变成一个不可变的对象。所有不可变对象都应该有一个 .toJS 方法来将它们变回常规 javascript objects/lists/whatever.
我在 link to solution on jsbin.com
上创建了轻巧的示例const initialState = Immutable.Map({
lines: Immutable.List([
Immutable.Map({id: 1, active: false, name: 'Some name'}),
Immutable.Map({id: 2, active: false, name: 'Sad name'}),
Immutable.Map({id: 3, active: true, name: 'Cool name'})
])
});
console.log('initialState', initialState.toJS())
// update lines, map over items and set active to false
const stateLinesAllNotActive = initialState.updateIn(
['lines'],
items => items.map((item) => item.set('active', false))
)
console.log('stateLinesAllNotActive', stateLinesAllNotActive.toJS())
// lines and key for item with id === 1, then set active to this item
const stateFirstActive = stateLinesAllNotActive.updateIn(
[
'lines',
stateLinesAllNotActive.get('lines').findIndex((item) => (item.get("id") === 1))
],
item => item.set("active", true)
)
console.log('stateFirstActive', stateFirstActive.toJS())