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

How to pass jade expression as mixin argument?

我有一个简单的 jade mixin:

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

但我想做的是像这样用玉语来表达标题:

  - 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

但是 jade 不喜欢这样 returns 一个错误

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

有什么方法可以实现吗?

Note the line 43 mentioned in the error doesn't exist in the file. This is suspicious

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

有一个解决方法:

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 的语法高亮很糟糕)

可以做到。

//- 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 代码会产生输出,但此输出不是 return 从函数中编辑的。相反,它被推送到输出流。这可能会导致奇怪的结果:

-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 语句,但您当然也可以 return 函数中的任何内容,并根据需要使用它。

最后,可以在变量中捕获 Jade 块。它依赖于 Jade 将输出放置在一个名为 "buf" 的数组中,所以这是一个 hack,因为它可能随时更改。

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.

this answer 中的信息导致了一个对我有用的解决方案...

你可以让你的标题成为mixin,动态调用你的mixin

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

mixin 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