Pri delu na zapletenih arhitekturah Sass ni redko uporabiti zemljevidov Sass za vzdrževanje konfiguracije in možnosti. Občasno boste znotraj zemljevidov (morda na več ravneh) videli zemljevide, kot je ta iz o-grid:
$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 );
Težava takih zemljevidov je, da iz ugnezdenega drevesa ni enostavno dobiti in nastaviti vrednosti. To je vsekakor nekaj, kar želite skriti znotraj funkcij, da se izognete vsakič ročnemu izvajanju.
Globoko pojdi
Pravzaprav je gradnja funkcije za pridobivanje globoko ugnezdenih vrednosti s zemljevida zelo enostavna.
/// 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; )
Če želimo na primer M
z našega konfiguracijskega zemljevida pridobiti vrednost, povezano s postavitvijo, je to enostavno:
$m-breakpoint: map-deep-get($o-grid-default-config, "layouts", "M"); // 610px
Navedite, da narekovaji okoli nizov niso obvezni. Dodajamo jih samo zaradi pomislekov glede berljivosti.
Globoko nastavljen
Po drugi strani pa je gradnja funkcije za nastavitev globoko ugnezdenega ključa lahko zelo dolgočasna.
/// 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; )
Zdaj, če želimo M
iz našega konfiguracijskega zemljevida posodobiti vrednost, povezano z postavitvijo, lahko naredimo:
$o-grid-default-config: map-deep-set($o-grid-default-config, "layouts" "M", 650px);
Dodatni viri
Zgornja funkcija ni edina rešitev te težave.
Knjižnica Sassy-Maps prav tako ponuja map-deep-set
in map-deep-get
deluje. V istem smislu je Hugo Giraudel napisal tudi extend
funkcijo v slogu jQuery, da vgrajeni map-merge
rekurzivnost združi več kot 2 zemljevida hkrati.