5

Rubyでは、メソッド内から添付のコードブロックに変数を簡単に渡すことができます。

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ミックスインでも同じことをしたいと思います。

=my-mixin
  @for $i from 1 to 8
    .grid-#{$i}
      @content

+my-mixin
  color: nth("red green blue orange yellow brown black purple", $i)

$ iはミックスイン宣言の内部で宣言されており、ミックスインが使用されている外部では表示されないため、このコードは機能しません。:(

だから...ミックスイン宣言内で宣言された変数をどのように活用しますか?

グリッドフレームワークとメディアクエリを使用する場合、この機能が非常に必要です。現在、DRYルールに違反して、必要になるたびにミックスイン宣言の内容を複製する必要があります。

UPD 2013-01-24

これが実際の例です。

ブレークポイントを循環し、提供されたコードをブレークポイントごとに1回適用するミックスインがあります。

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

このミックスインを使用するときは、@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内で使用できないため、これは機能しません。

@contentは一度解析され、ミックスインが解析される前に解析されるため、ミックスインを呼び出す前に変数を宣言しても役に立ちません。

代わりに、私がそれを必要とするたびに、私は2つの醜い太ももをしなければなりません:

  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スタイルを行う方法はありますか?

4

3 に答える 3

4

Sassの変数にはスコープがあります。それらは、それらが作成されたブロックでのみ表示されます。変数をミックスインの内部と外部の両方でアクセスできるようにする場合は、グローバルスコープで定義する必要があります。

$var: 0;

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

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

あなたが非常に長い間状態を気にしない$var限り、これはあなたの目的のためにうまくいくはずです。

@contentあなたの例では、が最初に処理されたように見えるため、これは機能しません。必要なのは、別の方法で記述されたミックスインです。

@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;
}

このようなミックスインには、任意の数の引数を指定できますが、必要に応じて使用することもできます@content

于 2012-12-27T13:42:06.237 に答える
1

私は自分でこの問題に遭遇しましたが、これはSASSの現在の制限です。

于 2013-06-10T12:03:17.867 に答える
1

したがって、これは現在Sassでは利用できません。

Sassの発行キューに関連するチケットがあります:https ://github.com/nex3/sass/issues/871計画された状態ですが、少なくともSass4.0まではおそらく到達しません。

于 2014-01-17T08:12:31.543 に答える