2016-08-02 39 views
3

Wie kann ich die Eigenschaft des Elements in ImmutableList({}) ändern, die in Immutable.Map({}) ist?Wie ändert man die Eigenschaft des Elements in ImmutableList ({}) in Immutable.Map ({})

ich habe:

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'}) 
    ]) 
}); 

Lets sagen, dass ich Artikel einstellen will mit id 1 in der Liste. Ändern Sie dann die Eigenschaft active in true. Ich möchte auch die Eigenschaft active für alle anderen Elemente in der Liste auf false setzen.

Wie mache ich das? Vielen Dank im Voraus.

Edit (Endlösung):

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 
     }); 
    }; 
} 
+0

was meinst du mit Änderung eines unveränderlichen? Der Punkt ist, dass Sie nicht können; Du musst duplizieren und zusammenführen ... – dandavis

+0

Ich möchte eine neue unveränderbare Karte mit neuen Werten zurückgeben. – Michal

+0

Wie kann ich es duplizieren und zusammenführen? Könnten Sie mir bitte ein Beispiel zeigen? Genau danach suche ich. – Michal

Antwort

2

Sie können unveränderlich wie so durchqueren (schnelle Anmerkung, obwohl ich Ihnen sehr empfehlen würde, das enti zu machen re Objekt unveränderlich). Sie können die Codezeilen halten und halten es ein bisschen mehr elegant durch nur mit unveränderlichen selbst -

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); 
     } 
    }) 
) 

Arbeits Geige See - https://jsfiddle.net/o04btr3j/214/

Dies aktualisiert die list Schlüssel in Ihrem Objekt (wenn es ist nicht dort, aus welchem ​​Grund auch immer es eine unveränderliche Liste ist), dann mappt über den Eigenschaften. Wenn es eine ID von 1 hat, setzt es active auf true, andernfalls setzt es active auf false.

Sie können auch nur initialState.toJS() Ihr unveränderliches Objekt und tun Sie Ihre Logik in einfachen js oder tun und immutableobject.get('property') und ändern und dann diese wieder in Ihrem Objekt festgelegt, aber ich würde empfehlen, nur die eingebauten Methoden in unveränderlich wie es zu verwenden ist viel weniger Code.

Auch, wenn ich mich nicht irre kann man nur so etwas tun:

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'} 
] 
}); 

Sie können immutable.fromJS() ein Objekt, um es in ein unveränderliches Objekt zu setzen. Und alle unveränderlichen Objekte sollten eine .toJS-Methode auf ihnen haben, um sie wieder in reguläre Javascript-Objekte/Listen/was auch immer zu verwandeln.

0

Was soll folgt arbeiten, aber, wie jemand gesagt ... Ich denke, könnte eine vollständige Aktualisierung besser ...

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>

+0

Das sieht gut aus. Ich bekomme aber einen Fehler: 'Uncaught TypeError: k ist keine Funktion' – Michal

+0

Ich habe eine Bearbeitung ... – Hitmands

+0

gemacht, aber jemand liebt es, zu downvooten ... es könnte akzeptiert werden? – Hitmands

1

Ich habe geschmeidiges Beispiel erstellt auf 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()) 
+0

Vielen Dank für Ihre Zeit. Ich akzeptierte nur die Antwort von Ajmajmajma. – Michal