如何将jade表达式作为mixin参数传递?

时间:2015-01-19 21:53:49

标签: javascript pug

我有一个简单的玉混合:

mixin event(title)
    .panel.panel-default
      .panel-heading !{title}
      .panel-body 
        if block
          block
        else
          p No content provided

我可以这样称呼它:

  - var title = "<a href='profile/@Carl'> @Carl</a>"

  +event ( title )
    | It wasn't that hard. But all in all I'm glad I did it
    | because I feel so much better now.
    br
    | Really. Thank god, it's over

但我想要做的是使用jade表达式作为标题:

  - var title = a(href='profile/@Carl') @Carl

  +event ( title )
    | It wasn't that hard. But all in all I'm glad I did it
    | because I feel so much better now.
    br
    | Really. Thank god, it's over

但是玉并不喜欢这样并且返回错误

SyntaxError: Unexpected character '@' (191:43)

有没有办法实现这一目标?

  

请注意,错误中提到的第43行并不存在于文件中。这很可疑

3 个答案:

答案 0 :(得分:1)

似乎将html作为字符串传递,就像您当前的解决方案是唯一的方法。 mixin的参数应该是js表达式

答案 1 :(得分:1)

有一种解决方法:

mixin event   
  block

  mixin contentDefault
    p No content provided

  .panel.panel-default
    .panel-heading
      +heading
    .panel-body
      +content

+event
  mixin heading
    a(href='profile/@Carl') @Carl
  mixin content
    |.
      It wasn't that hard. But all in all I'm glad I did it
      because I feel so much better now.
    br
    | Really. Thank god, it's over

+event
  mixin heading
    | Timothy
  mixin content
    +contentDefault

来自https://github.com/jadejs/jade/issues/631#issuecomment-70590841

(SO的语法突出显示糟透了BTW)

答案 2 :(得分:1)

可以做到。

//- Helper mixin to call a function or display straight text
mixin funcstr(f)
  | !{typeof f=="function"?(f.apply(this,[].slice.call(arguments,1)),''):''+f}

//- Original event mixin with special title
mixin event(title)
    .panel.panel-default
      .panel-heading
        //- Also illustrating passing params. Could call multiple times with different params here.
        +funcstr(title,'invoke param','other data')
      .panel-body 
        if block
          block
        else
          p No content provided

然后:

//- Usage of event without passing function
+event("hello")
  | Some text here

产生

<div class="panel panel-default">
  <div class="panel-heading">hello
  </div>
  <div class="panel-body"> Some text here
  </div>
</div>

//- Function to produce a title with a link, parameterized with a name
-function myTitle(name){return function(){
  a(href='profile/@#{name}') @#{name}
-}}

//- Usage of event with passing a function
+event(myTitle('Carl'))
  | It wasn't that hard. But all in all I'm glad I did it
  | because I feel so much better now.
  br
  | Really. Thank god, it's over

产生

<div class="panel panel-default">
  <div class="panel-heading"><a href="profile/@Carl">@Carl</a>
  </div>
  <div class="panel-body"> 
    It wasn't that hard. But all in all I'm glad I did it
    because I feel so much better now.<br/>Really. Thank god, it's over
  </div>
</div>

并且:

//-Functions can also be easily nested
-function moreTitle(name){return function(){ //Alternatively, binding also works nice
  div Profile link: #[+funcstr(myTitle(name))]. Enjoy.
  if (arguments.length)
    div Got passed '#{[].slice.call(arguments).join("', '")}'
  else
    div No params at final call time...
-}}

+event(moreTitle('Fred'))
  | There's really no reason to say more...

产生

<div class="panel panel-default">
  <div class="panel-heading">
    <div>Profile link: <a href="profile/@Fred">@Fred</a>. Enjoy.
    </div>
    <div>Got passed 'invoke param', 'other data'</div>
    </div>
  <div class="panel-body"> There's really no reason to say more...
  </div>
</div>

简而言之,您可以将任何Jade包装成一些JS,将其转换为函数。

请注意,函数中的Jade代码会生成输出,但不会从函数返回此输出。相反,它被推送到输出流。这可能会导致奇怪的结果:

-function info(){
| Great info!
-}

//Invoke and insert result into line (note: result is undefined: info() returns nothing)
//Invocation appends "Great info!" to the output. Afterward, "Important: " is appended to the output.
div Important: #{info()}

//Don't invoke until after "Important: " has been output. Invocation then appends "Great info!".
div Important: #[-info()]

产生

<!--Invoke and insert result into line (note: result is undefined: info() returns nothing)-->
<!--Invocation appends "Great info!" to the output. Afterward, "Important: " is appended to the output.-->
<div>Great info!Important: </div>
<!--Don't invoke until after "Important: " has been output. Invocation then appends "Great info!".-->
<div>Important: Great info!
</div>

所以,请注意当Jade混入时你如何调用自己的函数。

示例函数没有return语句,但您当然也可以从函数中返回任何内容,并根据需要使用它。

最后,可以在变量中捕获Jade块。它依赖于Jade将输出放在一个名为“buf”的数组中,因此它可以随时改变。

mixin capture(callback)
  - var s=buf,r;buf=[];
  block
  - r=buf.join('');buf=s;callback(r);

-var someHtml
+capture(function(captured){someHtml=captured})

  div
    h1 A Heading
    p A paragraph!


| Here's some html: !{someHtml}
| I captured it.

产生

Here's some html: 
<div>
  <h1>A Heading</h1>
  <p>A paragraph!</p>
</div>
I captured it.