Pri práci na zložitých architektúrach Sass nie je nezvyčajné používať mapy Sass na udržanie konfigurácie a možností. Z času na čas uvidíte mapy v mapách (možno na niekoľkých úrovniach), ako je táto, z 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 );
Problém s takýmito mapami je, že nie je ľahké získať a nastaviť hodnoty z vnoreného stromu. Toto je určite niečo, čo chcete skryť medzi funkciami, aby ste sa vyhli tomu, že to musíte zakaždým robiť ručne.
Hlboko dostať
Vytvorenie funkcie na získanie hlboko vnorených hodnôt z mapy je v skutočnosti veľmi ľahké.
/// 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; )
Napríklad, ak chceme získať hodnotu spojenú s M
rozložením z našej konfiguračnej mapy, je to také ľahké ako:
$m-breakpoint: map-deep-get($o-grid-default-config, "layouts", "M"); // 610px
Upozorňujeme, že úvodzovky okolo reťazcov sú voliteľné. Pridávame ich iba kvôli obavám o čitateľnosť.
Hlboká sada
Na druhej strane, budovanie funkcie na nastavenie hlboko vnoreného kľúča môže byť veľmi únavné.
/// 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; )
Teraz, ak chceme aktualizovať hodnotu spojenú s M
rozložením z našej konfiguračnej mapy, môžeme urobiť:
$o-grid-default-config: map-deep-set($o-grid-default-config, "layouts" "M", 650px);
Dodatočné zdroje
Vyššie uvedená funkcia nie je jediným riešením tohto problému.
Knižnica Sassy-Maps tiež poskytuje map-deep-set
a map-deep-get
funkcie. V rovnakom duchu napísal Hugo Giraudel aj extend
funkciu v štýle jQuery, aby bola vstavaná map-merge
rekurzívna a schopná zlúčiť viac ako 2 mapy naraz.