Deep Get / Set Mapsissa CSS-temppuja

Anonim

Kun työskentelet monimutkaisissa Sass-arkkitehtuureissa, ei ole harvinaista käyttää Sass-karttoja kokoonpanon ja vaihtoehtojen ylläpitämiseksi. Ajoittain näet karttoja kartoissa (mahdollisesti useilla tasoilla), kuten tämä o-ruudukosta:

$o-grid-default-config: ( columns: 12, gutter: 10px, min-width: 240px, max-width: 1330px, layouts: ( S: 370px, // ≥20px columns M: 610px, // ≥40px columns L: 850px, // ≥60px columns XL: 1090px // ≥80px columns ), fluid: true, debug: false, fixed-layout: M, enhanced-experience: true );

Tällaisten karttojen ongelmana on, että sisäkkäisen puun arvojen saaminen ja asettaminen ei ole helppoa. Tämä on ehdottomasti jotain, jonka haluat piilottaa toimintoihin, jotta sinun ei tarvitse tehdä sitä manuaalisesti joka kerta.

Syvä saada

Itse asiassa toiminnon rakentaminen syvälle sisäkkäisten arvojen noutamiseksi kartalta on erittäin helppoa.

/// Map deep get /// @author Hugo Giraudel /// @access public /// @param (Map) $map - Map /// @param (Arglist) $keys - Key chain /// @return (*) - Desired value @function map-deep-get($map, $keys… ) ( @each $key in $keys ( $map: map-get($map, $key); ) @return $map; )

Esimerkiksi, jos haluamme saada Masetteluun liittyvän arvon kokoonpanokartaltamme, se on yhtä helppoa kuin:

$m-breakpoint: map-deep-get($o-grid-default-config, "layouts", "M"); // 610px

Huomaa, että merkkijonojen ympärillä olevat lainaukset ovat valinnaisia. Lisäämme ne vain luettavuuden vuoksi.

Syvä sarja

Toisaalta toiminnon rakentaminen syvälle sisäkkäisen avaimen asettamiseksi voi olla hyvin tylsiä.

/// Deep set function to set a value in nested maps /// @author Hugo Giraudel /// @access public /// @param (Map) $map - Map /// @param (List) $keys - Key chaine /// @param (*) $value - Value to assign /// @return (Map) @function map-deep-set($map, $keys, $value) ( $maps: ($map,); $result: null; // If the last key is a map already // Warn the user we will be overriding it with $value @if type-of(nth($keys, -1)) == "map" ( @warn "The last key you specified is a map; it will be overrided with `#($value)`."; ) // If $keys is a single key // Just merge and return @if length($keys) == 1 ( @return map-merge($map, ($keys: $value)); ) // Loop from the first to the second to last key from $keys // Store the associated map to this key in the $maps list // If the key doesn't exist, throw an error @for $i from 1 through length($keys) - 1 ( $current-key: nth($keys, $i); $current-map: nth($maps, -1); $current-get: map-get($current-map, $current-key); @if $current-get == null ( @error "Key `#($key)` doesn't exist at current level in map."; ) $maps: append($maps, $current-get); ) // Loop from the last map to the first one // Merge it with the previous one @for $i from length($maps) through 1 ( $current-map: nth($maps, $i); $current-key: nth($keys, $i); $current-val: if($i == length($maps), $value, $result); $result: map-merge($current-map, ($current-key: $current-val)); ) // Return result @return $result; )

Nyt, jos haluamme päivittää Masetteluun liittyvän arvon kokoonpanokartastamme, voimme tehdä:

$o-grid-default-config: map-deep-set($o-grid-default-config, "layouts" "M", 650px);

Lisäresursseja

Yllä oleva toiminto ei ole ainoa ratkaisu tähän ongelmaan.

Myös Sassy-Maps-kirjasto tarjoaa map-deep-setja map-deep-gettoimii. Samoilla linjoilla Hugo Giraudel on myös kirjoittanut jQuery-tyylisen extendtoiminnon, joka tekee sisäänrakennetusta map-mergerekursiiviseksi ja pystyy yhdistämään yli kaksi karttaa kerralla.