Дееп Гет / Сет у Мапама - ЦСС-трикови

Anonim

Када радите на сложеним Сассовим архитектурама, није реткост да се Сассове мапе користе за одржавање конфигурације и опција. Повремено ћете видети мапе у мапама (могуће на неколико нивоа) попут ове из о-грид:

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

Проблем таквих мапа је што није лако добити и поставити вредности из угнежђеног стабла. Ово је дефинитивно нешто што желите да сакријете унутар функција како бисте избегли да то сваки пут радите ручно.

Дубоко

Заправо, изградња функције за преузимање дубоко угнежђених вредности са мапе је врло једноставна.

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

На пример, ако желимо да добијемо вредност повезану са Mизгледом са наше мапе конфигурације, то је лако као:

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

Имајте на уму да наводници око низова нису обавезни. Додајемо их само због забринутости за читљивост.

Дубоко постављен

С друге стране, изградња функције за постављање дубоко угнежђеног кључа може бити врло заморна.

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

Сада ако желимо да ажурирамо вредност повезану са Mизгледом са наше мапе конфигурације, можемо да урадимо:

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

Додатни ресурси

Горе наведена функција није једино решење овог проблема.

Библиотека Сасси-Мапс такође пружа map-deep-setи map-deep-getфункционише. У складу са истим линијама, Хуго Гираудел је такође написао extendфункцију у стилу јКуери да би уграђена map-mergeрекурзива могла да споји више од 2 мапе одједном.