2012-12-27 44 views
5

在Ruby中,你可以很容易地從一個方法裏傳遞一個變量進入連接的代碼塊:將mixin聲明中的變量傳遞給附加的內容塊?

def mymethod 
    (1..10).each { |e| yield(e * 10) } # Passes a number to associated block 
end 

mymethod { |i| puts "Here comes #{i}" } # Outputs the number received from the method 

我想這樣做在SASS混入同樣的事情:

​​

此代碼韓元不工作,因爲$ i是在mixin聲明中聲明的,並且不能在外部使用mixin。 :(

所以...我如何充分利用混入聲明中聲明的變量?

當我與網格框架和媒體查詢工作,我很喜歡這個功能。目前,我有重複裏面有什麼的每次我需要它,違反了乾燥的原則時混入聲明。

UPD 2013年1月24日

這裏有一個真實的例子。

我有一個mixi網n表示通過斷點週期,一旦應用所提供的代碼爲每一個斷點:

=apply-to-each-bp 
    @each $bp in $bp-list 
    +at-breakpoint($bp) // This is from Susy gem 
     @content 

當我使用這個mixin的我必須使用內@content這個$ BP值。它可能是這樣的:

// Applies to all direct children of container 
.container > * 
    display: inline-block 

// Applies to all direct children of container, 
// if container does not have the .with-gutters class 
.container:not(.with-gutters) > * 
    +apply-to-each-bp 
    width: 100%/$bp 

// Applies to all direct children of container, 
// if container has the .with-gutters class 
.container.with-gutters > * 
    +apply-to-each-bp 
    $block-to-margin-ratio: 0.2 
    $width: 100%/($bp * (1 + $block-to-margin-ratio) - $block-to-margin-ratio) 
    width: $width 
    margin-right: $width * $block-to-margin-ratio 

    &:nth-child(#{$bp}) 
     margin-right: 0 

但是這不起作用,因爲$ bp的值在@content中不可用。

在調用mixin之前聲明變量不會有幫助,因爲在解析mixin之前@content會被解析一次。

取而代之的是,每一次我需要,我需要做的二醜大腿:

  1. 宣告一個特設的混入,
  2. 寫週期,違反了DRY原則:
// Each of the following mixins is mentioned in the code only once. 
=without-gutters($bp) 
    width: 100%/$bp 

=with-gutters($bp) 
    $block-to-margin-ratio: 0.2 
    $width: 100%/($bp * (1 + $block-to-margin-ratio) - $block-to-margin-ratio) 
    width: $width 
    margin-right: $width * $block-to-margin-ratio 

    &:nth-child(#{$bp}) 
    margin-right: 0 

// Applies to all direct children of container 
.container > * 
    display: inline-block 

// Applies to all direct children of container, 
// if container does not have the .with-gutters class 
.container:not(.with-gutters) > * 
    @each $bp in $bp-list 
    +at-breakpoint($bp) // This is from Susy gem 
     +without-gutters($bp) 

// Applies to all direct children of container, 
// if container has the .with-gutters class 
.container.with-gutters > * 
    @each $bp in $bp-list // Duplicate code! :(
    +at-breakpoint($bp) // Violates the DRY principle. 
     +with-gutters($bp) 

所以,問題是:有沒有辦法做到這一點的Ruby風格?

回答

1

所以這是Sass當前無法使用的。

在Sass問題隊列中有一個相關的故障單:https://github.com/nex3/sass/issues/871它處於計劃狀態,但可能不會達到Sass 4.0的水平。

4

薩斯變量有範圍給他們。他們只是在他們創建塊可見如果您希望變量是內部和混入的外部訪問,就必須在全球範圍內進行定義:

$var: 0; 

@mixin test { 
    $var: $var + 1; 
    color: red; 
} 

.test { 
    $var: 5; 
    @include test; 
    @debug $var; // DEBUG: 6 
} 

只要你不要在乎$var很長的狀態,這應該爲你的目的而行。

對於您的示例,這不起作用,因爲它看起來像首先處理@content。你需要的是形式,它不同的一個mixin:

@mixin test($properties...) { 
    @for $i from 1 to 8 { 
     .grid-#{$i} { 
      @each $p in $properties { 
       $list: nth($p, 2); 
       @if length($list) > 1 { 
        #{nth($p, 1)}: nth($list, $i); 
       } @else { 
        #{nth($p, 1)}: $list; 
       } 
      } 
      @content; 
     } 
    } 
} 

.test { 
    @include test(color (red green blue orange yellow brown black purple)); 
} 

生成CSS:

.test .grid-1 { 
    color: red; 
} 

.test .grid-2 { 
    color: green; 
} 

.test .grid-3 { 
    color: blue; 
} 

.test .grid-4 { 
    color: orange; 
} 

.test .grid-5 { 
    color: yellow; 
} 

.test .grid-6 { 
    color: brown; 
} 

.test .grid-7 { 
    color: black; 
} 

這樣一個mixin可以喂任何數量的參數,仍然可以讓你,如果你想使用@content

+0

尊敬的cimmanon,您提出的解決方案不適用於這種情況。我編輯了我的第一個問題,以添加一個完整的,幾乎是現實生活的例子,我正在尋找。請看看並寫下你的考慮。 –

1

我已經遇到了這個問題我自己和AFAIK這是目前在SASS限制。

相關問題