Khi làm việc trên các kiến trúc Sass phức tạp, không có gì lạ khi sử dụng bản đồ Sass để duy trì cấu hình và các tùy chọn. Đôi khi, bạn sẽ thấy các bản đồ trong bản đồ (có thể ở một số cấp độ) như bản đồ này từ 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 );
Vấn đề với các bản đồ như vậy là không dễ dàng lấy và thiết lập các giá trị từ cây lồng nhau. Đây chắc chắn là thứ bạn muốn ẩn bên trong các hàm để tránh phải thực hiện thủ công mỗi lần.
Nhận sâu
Trên thực tế, việc xây dựng một hàm để tìm nạp các giá trị lồng nhau sâu từ bản đồ là rất dễ dàng.
/// 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; )
Ví dụ: nếu chúng ta muốn nhận giá trị được liên kết với M
bố cục từ bản đồ cấu hình của mình, nó dễ dàng như sau:
$m-breakpoint: map-deep-get($o-grid-default-config, "layouts", "M"); // 610px
Lưu ý rằng dấu ngoặc kép xung quanh chuỗi là tùy chọn. Chúng tôi chỉ thêm chúng cho các mối quan tâm về khả năng đọc.
Tập hợp sâu
Mặt khác, việc xây dựng một chức năng để đặt một khóa lồng nhau sâu có thể rất tẻ nhạt.
/// 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; )
Bây giờ, nếu chúng ta muốn cập nhật giá trị được liên kết với M
bố cục từ bản đồ cấu hình của mình, chúng ta có thể thực hiện:
$o-grid-default-config: map-deep-set($o-grid-default-config, "layouts" "M", 650px);
Các nguồn bổ sung
Chức năng trên không phải là giải pháp duy nhất cho vấn đề này.
Thư viện Sassy-Maps cũng cung cấp map-deep-set
và map-deep-get
hoạt động. Cùng với đó, Hugo Giraudel cũng đã viết một extend
hàm kiểu jQuery để làm cho map-merge
đệ quy tích hợp sẵn và có thể hợp nhất nhiều hơn 2 bản đồ cùng một lúc.