Saat mengerjakan arsitektur Sass yang kompleks, tidak jarang menggunakan peta Sass untuk mempertahankan konfigurasi dan opsi. Dari waktu ke waktu, Anda akan melihat peta dalam peta (mungkin pada beberapa level) seperti ini dari 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 );
Masalah dengan peta semacam itu adalah tidak mudah untuk mendapatkan dan menetapkan nilai dari pohon bersarang. Ini jelas sesuatu yang ingin Anda sembunyikan di dalam fungsi untuk menghindari keharusan melakukannya secara manual setiap saat.
Dapatkan jauh
Sebenarnya, membuat fungsi untuk mengambil nilai yang sangat bertingkat dari peta sangat mudah.
/// 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; )
Misalnya, jika kita ingin mendapatkan nilai yang terkait dengan M
tata letak dari peta konfigurasi kita, itu semudah:
$m-breakpoint: map-deep-get($o-grid-default-config, "layouts", "M"); // 610px
Perhatikan bahwa kutipan di sekitar string bersifat opsional. Kami hanya menambahkannya untuk masalah keterbacaan.
Set dalam
Di sisi lain, membuat fungsi untuk menyetel kunci yang sangat bertingkat bisa sangat membosankan.
/// 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; )
Sekarang jika kita ingin memperbarui nilai yang terkait dengan M
tata letak dari peta konfigurasi kita, kita dapat melakukan:
$o-grid-default-config: map-deep-set($o-grid-default-config, "layouts" "M", 650px);
Sumber daya tambahan
Fungsi di atas bukanlah satu-satunya solusi untuk masalah ini.
Perpustakaan Sassy-Maps juga menyediakan map-deep-set
dan map-deep-get
berfungsi. Sejalan dengan itu, Hugo Giraudel juga telah menulis extend
fungsi gaya jQuery untuk membuat map-merge
rekursif bawaan dan mampu menggabungkan lebih dari 2 peta sekaligus.