Làm cách nào để sử dụng underscore.js làm công cụ mẫu?


262

Tôi đang cố gắng tìm hiểu về cách sử dụng javascript mới như một ngôn ngữ máy chủ và là ngôn ngữ chức năng. Vài ngày trước tôi đã nghe nói về node.js và express framework. Sau đó, tôi thấy về underscore.js là một tập hợp các hàm tiện ích. Tôi thấy câu hỏi này trên stackoverflow . Nó nói rằng chúng ta có thể sử dụng underscore.js làm công cụ mẫu. bất cứ ai cũng biết các hướng dẫn tốt về cách sử dụng underscore.js để tạo khuôn mẫu, đặc biệt là đối với những người lớn có ít kinh nghiệm với javascript nâng cao. Cảm ơn


12
Trong phòng thủ "Luke's", phiên bản cải tiến của hướng dẫn sử dụng ít nhất là sớm nhất là tháng 5 không có cách sử dụng nâng cao
Shanimal

Tôi chỉ trả lời một câu hỏi tương tự cũng có lợi cho câu hỏi của bạn. stackoverflow.com/questions/28136101/retrieve-column-in-parse/ory
jeffdill2

Câu trả lời:


475

Tất cả mọi thứ bạn cần biết về mẫu gạch dưới có ở đây . Chỉ có 3 điều cần ghi nhớ:

  1. <% %> - để thực thi một số mã
  2. <%= %> - để in một số giá trị trong mẫu
  3. <%- %> - để in một số giá trị HTML đã thoát

Đó là tất cả về nó.

Ví dụ đơn giản:

var tpl = _.template("<h1>Some text: <%= foo %></h1>");

sau đó tpl({foo: "blahblah"})sẽ được kết xuất thành chuỗi<h1>Some text: blahblah</h1>


55
Tôi không hiểu tại sao ai sẽ xuống bỏ phiếu này, đó là những câu trả lời kinh điển và các điểm đến các hướng dẫn trên trang chủ của dự án, đó là "dạy một người đàn ông cá" cổ điển.
Jon z

1
Tôi nghĩ rằng họ sẽ bỏ phiếu vì tài liệu họ cung cấp cung cấp rất ít về cách kết hợp <% và <% = ngoài ví dụ số ít của họ và cách chuyển từ <% = sang print () thay đổi mẫu đó. Ngoài ra, khi sử dụng 'nội suy', có một số hành vi kỳ quặc có thể sẽ tạo ra cảnh với một chút giải thích. Một lần nữa, không được cung cấp. Mặc dù tôi đồng ý, nhưng thật ngu ngốc khi bỏ phiếu.
Queue Hammer

8
3. <% -%> - để in một số giá trị với HTML đã thoát
LeeGee

13
Tôi đã không downvote, nhưng câu trả lời của bạn không làm gì cả (ngoài việc cung cấp một liên kết) để giải thích cách sử dụng underscore.js làm công cụ mẫu. Câu trả lời của bạn cung cấp một "bảng cheat" nhanh chóng có lẽ cho những người đã nhận được nó, nhưng bản thân nó, nó không phải là một câu trả lời cho câu hỏi. Tôi cho rằng nó có nhiều upvote như nó.
Zach Lysobey

1
-1, tài liệu bị thiếu ở nhiều khía cạnh. Gần như chắc chắn rằng người dùng đã đến đây sau khi tham khảo tài liệu. Câu trả lời kém.
Matt Parkins

198
<!-- Install jQuery and underscore -->

<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="http://documentcloud.github.com/underscore/underscore-min.js"></script>

<!-- Create your template -->
<script type="foo/bar" id='usageList'>
<table cellspacing='0' cellpadding='0' border='1' >
    <thead>
      <tr>
        <th>Id</th>
        <th>Name</th>
      </tr>
    </thead>
    <tbody>
      <%
        // repeat items 
        _.each(items,function(item,key,list){
          // create variables
          var f = item.name.split("").shift().toLowerCase();
      %>
        <tr>
          <!-- use variables -->
          <td><%= key %></td>
          <td class="<%= f %>">
            <!-- use %- to inject un-sanitized user input (see 'Demo of XSS hack') -->
            <h3><%- item.name %></h3>
            <p><%- item.interests %></p>
          </td>
        </tr>
      <%
        });
      %>
    </tbody>
  </table>
</script>

<!-- Create your target -->

<div id="target"></div>

<!-- Write some code to fetch the data and apply template -->

<script type="text/javascript">
  var items = [
    {name:"Alexander", interests:"creating large empires"},
    {name:"Edward", interests:"ha.ckers.org <\nBGSOUND SRC=\"javascript:alert('XSS');\">"},
    {name:"..."},
    {name:"Yolando", interests:"working out"},
    {name:"Zachary", interests:"picking flowers for Angela"}
  ];
  var template = $("#usageList").html();
  $("#target").html(_.template(template,{items:items}));
</script>
  • JsFiddle Cảm ơn @PHearst!
  • JsFiddle (mới nhất)
  • Danh sách JsFiddle được nhóm theo chữ cái đầu tiên (ví dụ phức tạp w / hình ảnh, lời gọi hàm, mẫu phụ) rẽ nhánh! có một vụ nổ ...
  • JsFiddle Demo về hack XSS được ghi nhận bởi @tarun_telang bên dưới
  • JsFiddle Một phương pháp không chuẩn để làm các mẫu con

17
Cảm ơn bạn đã sử dụng rõ ràng thẻ script "text / html" trong ví dụ của bạn; Tôi chưa quen với underscore.js và tôi đã đọc sai tài liệu một cách đáng tiếc - thật tuyệt khi biết templateString không phải luôn được viết nội tuyến.
aschyiel

Mẫu không thực sự text/htmlnói như vậy type="text/html"là dối trá, dối trá có thể gây ra vấn đề. Bạn sẽ tốt hơn với một loại chính xác như text/x-underscore.
mu quá ngắn

6
mu, tôi nghĩ thật tốt khi chỉ ra rằng nó không quan trọng. Hãy đối mặt với nó, bất cứ điều gì bạn đặt ra là một lời nói dối. text / x-underscore là một lời nói dối lớn hơn bởi vì tôi sử dụng lodash, lol :) Trong JsFiddle cuối cùng tôi đã thêm type="foo/bar"vì tôi muốn mọi người biết rằng nó không quan trọng miễn là trình duyệt / máy chủ không nhận ra nó và thử để làm một cái gì đó với nó. Vì html không phải là một loại tập lệnh, tôi cảm thấy khá an toàn với văn bản / html (John Resig sử dụng nó) foo / bar cũng hoạt động :)
Shanimal

4
Mọi người không đồng ý với tôi mọi lúc, tôi cố hết sức để không nhận nó một cách cá nhân (ngay cả khi đó là cá nhân :). Tôi đã bị đốt cháy bởi các tác dụng phụ ngoài ý muốn của sự chậm chạp nhỏ lặp đi lặp lại nhiều lần vì vậy thói quen của tôi là sai lầm ở khía cạnh nghiêm ngặt. Thông số kỹ thuật loại MIME thực sự dự trữ */x-*các loại cho việc sử dụng "tạo thành", tôi không nghĩ có một text/underscoreloại trong sổ đăng ký chính thức nên tôi sử dụng text/x-underscorevì tôi bị hoang tưởng và họ thực sự ra ngoài để lấy tôi.
mu quá ngắn

1
hãy biết rằng bản demo XSS không còn hoạt động nữa vì các trình duyệt từ chối thực thi JS với một
mô phỏng

94

Ở dạng đơn giản nhất, bạn sẽ sử dụng nó như sau:

var html = _.template('<li><%= name %></li>', { name: 'John Smith' });
//html is now '<li>John Smith</li>'   

Nếu bạn sẽ sử dụng một vài lần mẫu, bạn sẽ muốn biên dịch nó để nó nhanh hơn:

var template = _.template('<li><%= name %></li>');

var html = [];
for (var key in names) {
    html += template({ name: names[i] });
}

console.log(html.join('')); //Outputs a string of <li> items

Cá nhân tôi thích cú pháp kiểu Mustache. Bạn có thể điều chỉnh các dấu hiệu mã thông báo mẫu để sử dụng dấu ngoặc nhọn:

_.templateSettings.interpolate = /\{\{(.+?)\}\}/g;

var template = _.template('<li>{{ name }}</li>');

Mẹo nội suy Mustache đã giúp tôi trong khi sử dụng chế độ xem express3 được hiển thị bằng ejs. Cảm ơn!
micrub

Để sử dụng các mẫu từ chế độ xem, bạn có thể có các phần sau trong đánh dấu trang của mình: <script type = "text / template" id = "my-template"> <div> <% - name%> </ div> </ script > và sau đó thực hiện các thao tác sau trong JS của bạn: var html = _.template ($ ('# my-template'). html (), {name: "John Smith"});
Gaurav Gupta

2
@evilcelery - interpolatemẹo của bạn không hoạt động, nhưng điều này đã làm:_.templateSettings = { interpolate: /\{\{\=(.+?)\}\}/g, escape: /\{\{\-(.+?)\}\}/g, evaluate: /\{\{(.+?)\}\}/g };
vsync

28

Các tài liệu cho templating là một phần, tôi đã xem nguồn.

Hàm _.template có 3 đối số:

  1. Chuỗi văn bản : chuỗi mẫu
  2. Dữ liệu đối tượng : dữ liệu đánh giá
  3. Cài đặt đối tượng : cài đặt cục bộ, _.templateS Settings là đối tượng cài đặt chung

Nếu không có dữ liệu (hoặc null) nào được cung cấp, thì chức năng kết xuất sẽ được trả về. Nó có 1 đối số:

  1. Dữ liệu đối tượng : giống như dữ liệu trên

Có 3 mẫu regex và 1 tham số tĩnh trong cài đặt:

  1. Đánh giá RegExp : "<% code%>" trong chuỗi mẫu
  2. Nội suy RegExp : "<% = code%>" trong chuỗi mẫu
  3. RegExp thoát : "<% - mã%>"
  4. Biến chuỗi : tùy chọn, tên của tham số dữ liệu trong chuỗi mẫu

Mã trong một phần đánh giá sẽ được đánh giá đơn giản. Bạn có thể thêm chuỗi từ phần này bằng lệnh __p + = "mystring" vào mẫu được đánh giá, nhưng điều này không được khuyến nghị (không phải là một phần của giao diện tạo khuôn mẫu), sử dụng phần nội suy thay vì đó. Loại phần này là để thêm các khối như nếu hoặc cho mẫu.

Kết quả của mã trong phần nội suy sẽ được thêm vào mẫu được đánh giá. Nếu null được trả lại, thì chuỗi rỗng sẽ được thêm vào.

Các thoát phần thoát html với _.escape trên giá trị trở lại của mã nhất định. Vì vậy, nó tương tự như một _.escape (mã) trong phần nội suy , nhưng nó thoát với \ các ký tự khoảng trắng như \ n trước khi nó chuyển mã đến _.escape . Tôi không biết tại sao điều đó lại quan trọng, nó nằm trong mã, nhưng nó hoạt động tốt với phép nội suy_.escape - không thoát khỏi các ký tự khoảng trắng - cũng vậy.

Theo mặc định, tham số dữ liệu được truyền bằng câu lệnh with (data) {...} , nhưng kiểu đánh giá này chậm hơn nhiều so với đánh giá với biến được đặt tên. Vì vậy, đặt tên dữ liệu với biến tham số là một cái gì đó tốt ...

Ví dụ:

var html = _.template(
    "<pre>The \"<% __p+=_.escape(o.text) %>\" is the same<br />" +
        "as the  \"<%= _.escape(o.text) %>\" and the same<br />" +
        "as the \"<%- o.text %>\"</pre>",
    {
        text: "<b>some text</b> and \n it's a line break"
    },
    {
        variable: "o"
    }
);

$("body").html(html);

các kết quả

The "<b>some text</b> and 
 it's a line break" is the same
as the "<b>some text</b> and 
 it's a line break" and the same
as the "<b>some text</b> and 
 it's a line break"

Bạn có thể tìm thấy ở đây nhiều ví dụ hơn về cách sử dụng mẫu và ghi đè cài đặt mặc định: http://underscorejs.org/#template

Bằng cách tải mẫu, bạn có nhiều tùy chọn, nhưng cuối cùng, bạn luôn phải chuyển đổi mẫu thành chuỗi. Bạn có thể cung cấp cho nó như một chuỗi bình thường như ví dụ ở trên hoặc bạn có thể tải nó từ thẻ script và sử dụng hàm .html () của jquery hoặc bạn có thể tải nó từ một tệp riêng biệt với plugin tpl của allow.js .

Một lựa chọn khác để xây dựng cây dom với laconic thay vì templating.


21

Tôi đang đưa ra một ví dụ rất đơn giản

1)

var data = {site:"mysite",name:"john",age:25};
var template = "Welcome you are at <%=site %>.This has been created by <%=name %> whose age is <%=age%>";
var parsedTemplate = _.template(template,data);
console.log(parsedTemplate); 

Kết quả sẽ là

Welcome you are at mysite.This has been created by john whose age is 25.

2) Đây là một mẫu

   <script type="text/template" id="template_1">
       <% _.each(items,function(item,key,arr) { %>
          <li>
             <span><%= key %></span>
             <span><%= item.name %></span>
             <span><%= item.type %></span>
           </li>
       <% }); %>
   </script>

Đây là html

<div>
  <ul id="list_2"></ul>
</div>

Đây là mã javascript chứa đối tượng json và đưa mẫu vào html

   var items = [
       {
          name:"name1",
          type:"type1"
       },
       {
          name:"name1",
          type:"type1"
       },
       {
          name:"name1",
          type:"type1"
       },
       {
          name:"name1",
          type:"type1"
       },
       {
          name:"name1",
          type:"type1"
       } 
   ];
  $(document).ready(function(){
      var template = $("#template_1").html();
      $("#list_2").html(_.template(template,{items:items}));
  });


14

với cách thể hiện thật dễ dàng. tất cả những gì bạn cần là sử dụng mô-đun hợp nhất trên nút để bạn cần cài đặt nó:

npm install consolidate --save

sau đó bạn nên thay đổi công cụ mặc định thành mẫu html bằng cách này:

app.set('view engine', 'html');

đăng ký công cụ mẫu gạch dưới cho phần mở rộng html:

app.engine('html', require('consolidate').underscore);

xong rôi !

Bây giờ để tải ví dụ một mẫu có tên 'index.html':

res.render('index', { title : 'my first page'});

có lẽ bạn sẽ cần phải cài đặt mô-đun gạch dưới.

npm install underscore --save

Tôi hy vọng điều này đã giúp bạn!


12

Tôi muốn chia sẻ một phát hiện quan trọng hơn.

việc sử dụng <% = biến => sẽ dẫn đến lỗ hổng kịch bản chéo trang. Vì vậy, an toàn hơn để sử dụng <% - biến -> thay vào đó.

Chúng tôi đã phải thay thế <% = bằng <% - để ngăn chặn các cuộc tấn công kịch bản chéo trang. Không chắc chắn, liệu điều này sẽ có bất kỳ tác động đến hiệu suất


2
+1 Tôi đã thêm một ghi chú về XSS vào ví dụ của mình. Đây là một điểm thực sự tốt về việc tiêm thông tin người dùng không được xác nhận vào một trang web. thông qua một công cụ mẫu hoặc thậm chí $ .html ().
Tối thiểu

1

Lodash cũng giống nhau Đầu tiên viết một kịch bản như sau:

<script type="text/template" id="genTable">
<table cellspacing='0' cellpadding='0' border='1'>
        <tr>
            <% for(var prop in users[0]){%>
            <th><%= prop %> </th>
            <% }%>
        </tr>
        <%_.forEach(users, function(user) { %>
            <tr>
                 <% for(var prop in user){%>
                    <td><%= user[prop] %> </td>
                <% }%>

            </tr>
        <%})%>
</table>

Bây giờ viết một số JS đơn giản như sau:

var arrOfObjects = [];
for (var s = 0; s < 10; s++) {
    var simpleObject = {};
    simpleObject.Name = "Name_" + s;
    simpleObject.Address = "Address_" + s;
    arrOfObjects[s] = simpleObject;
}
var theObject = { 'users': arrOfObjects }
var compiled = _.template($("#genTable").text());
var sigma = compiled({ 'users': myArr });

$(sigma).appendTo("#popup");

Trong đó popoup là div nơi bạn muốn tạo bảng

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.