0

Tìm hiểu về Meteor (phần 3) - Templates

Ở phần trước tôi cùng các bạn đã học cách để tạo một ứng dụng meteor đơn giản. Ở phần 2 này chúng ta cùng nhau đi tìm hiểu một thành phần khá quan trọng trong việc phát triển ứng dụng meteor đó là Templates. Để dễ dàng vào phát triển Meteor, chúng ta sẽ áp dụng một phương pháp tiếp cận từ ngoài vào trong. Nói cách khác, chúng ta sẽ xây dựng một HTML / JavaScript “dump” bao bọc bên ngoài, và sau đó gắn nó vào bên trong ứng dụng của chúng ta. Điều này có nghĩa là trong chương này chúng ta sẽ chỉ để quan tâm đến những gì đang xảy ra bên trong thư mục /client. Nếu bạn vẫn chưa tạo, hãy bắt đầu bằng việc tạo ra một file tên là main.html bên trong thư mục /client và thêm vào đoạn code sau:

<head>
  <title>Framgia VietNam</title>
</head>
<body>
  <div class="container">
    <header class="navbar navbar-default" role="navigation"> 
      <div class="navbar-header">
        <a class="navbar-brand" href="/">Framgia VietNam</a>
      </div>
    </header>
    <div id="main" class="row-fluid">
          {{> postsList}}
    </div>
  </div>
</body>

Đây sẽ là template chính cho ứng dụng của chúng ta. Như bạn có thể nhìn thấy đoạn code hầu như là HTML ngoại trừ tag {{> postsList}} mục đích để thêm template vào, nó chèn vào template postsList tới ngay sau đây. Bây giờ, hãy cùng tạo ra một vài template nữa.

Meteor Templates

Về mặt cốt lõi, một trang tin tức mạng xã hội được kết cấu từ những bài viết sắp xếp thành danh sách, và đó cũng sẽ là điều mà chúng ta sẽ làm với các templete. Hãy tạo một thư mục / templates bên trong / client. Đây sẽ là nơi chúng ta đặt tất cả template vào, và để giữ cho mọi thứ gọn gàng, chúng tôi cũng sẽ tạo ra thư mục / posts bên trong/ templates để lưu trữ những template liên quan đến việc post bài viết. Cuối cùng thì chúng ta đã sẵn sàng để tạo ra template thứ hai. Bên trong thư mục client / templates / posts, tạo ra file posts_list.html với nội dung như sau:

<template name="postsList">
  <div class="posts">
    {{#each posts}}
      {{> postItem}}
    {{/each}}
  </div>
</template>

Và post_item.htmlvới nội dung như sau:

<template name="postItem">
  <div class="post">
    <div class="post-content">
      <h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3>
    </div>
  </div>
</template>

Lưu ý đến thuộc tính name =" postsList " của phần tử template. Đây là tên sẽ được sử dụng bởi Meteor để biết được template nào đang ở đâu (chú ý răng tên thực của file không liên quan). Bây giờ, hãy cùng xem xét tới hệ thống Template của Meteor, là Spacebars. Spacebars đơn giản chỉ là HTML, với ba thứ được thêm vào: inclusions (cũng được biết đến như là “partials”), expressions và block helpers. Inclusions sử dụng cú pháp {{> templateName}} , công việc của nó đơn giản chỉ là bảo Meteor thay thế đoạn mã với template tương ứng (trong trường hợp của chúng ta là postItem). Biểu thức , ví dụ như là {{title}} hoặc là gọi đến một thuộc tính của object hiện tại, hoặc là trả về giá trị của một template helper đã được định nghĩa trong trình quản lý template (sẽ tìm hiểu sau). Cuối cùng, block helper là những tag đặc biệt điều khiển luồng của template, ví dụ như {{#each}}…{{/each}} hoặc {{#if}}…{{/if}}. Gắn kết những kiến thức kể trên, chúng ta có thể bắt đầu hiểu những gì đang xảy ra ở đây. Đầu tiên, trong template postsList, chúng ta lặp qua object post với block helper {{#each}}…{{/each}}. Sau đó, với mỗi thành phần, chúng ta thêm vào template postItem. Vậy template postItem này tới từ đâu? Đây là một câu hỏi hay. Nó thực ra là một template helper, và bạn có thể suy nghĩ nó như là một chỗ giữ cho giá trị thay đổi. Bản thân template postItem khá là dễ hiểu. Nó chỉ dùng đúng ba biểu thức: {{url}} và {{title}}đều trả về thuộc tính của tài liệu, và {{domain}}gọi tới tempalte helper.

Template Helpers

Cho đến bây giờ, chúng ta đã làm việc với Spacebars, thứ thực ra là HTML nhưng với một vài tag thêm vào. Không giống như ngôn ngữ khác, như PHP chẳng hạn (hoặc như HTML thuần, có thể chứa JavaScript), Meteor giữ template và phần logic độc lập, và những template này bản thân nó thực tế không làm nhiều việc. Theo trình tự, một template cần có helper. Bạn có thể nghĩ helper như là những người đầu bếp lấy nguyên liệu thô (dữ liệu của bạn) và chuẩn bị chúng, trước khi truyền ra đĩa (template) tới người phục vụ, là người sẽ đưa ra cho bạn. Nói cách khác, trong khi mục đích của template giới hạn trong việc hiển thị hoặc tạo vòng lặp trên các biến, helper là người thực sự làm công việc phức tạp gán giá trị cho các biến. Để mọi thứ được đơn giản, chúng ta sẽ dùng giữ luật đặt tên file chứa helper của một template giống tên của template, nhưng với đuôi là .js. Vậy hãy cùng tạo ra file posts_list.js bên trong thư mục /client/templates/posts và bắt đầu viết helper đầu tiên:

var postsData = [
  {
    title: 'Introducing Framgia VietNam',
    url: 'http://recruit.framgia.vn/'
  }, 
  {
    title: 'Meteor',
    url: 'http://meteor.com'
  }, 
  {
    title: 'The Meteor Book',
    url: 'http://themeteorbook.com'
  }
];
Template.postsList.helpers({
  posts: postsData
});

Nếu bạn thực hành đúng, bạn sẽ thấy màn hình như sau trong trình duyệt: Chúng tôi đang làm hai việc ở đây. Đầu tiên, chúng tôi đang thiết lập một số dữ liệu mẫu dummy trong mảng postsData. Dữ liệu mà thông thường sẽ đến từ các cơ sở dữ liệu, nhưng kể từ khi chúng tôi đã không nhìn thấy như thế nào để làm điều đó chưa (chờ cho chương tiếp theo!), Chúng tôi đang “gian lận” bằng cách sử dụng dữ liệu tĩnh. Thứ hai, chúng tôi đang sử dụng Template.postsList.helpers Meteor () chức năng để tạo ra một helper mẫu gọi là posts trả vềpostsData mảng chúng ta vừa định nghĩa ở trên. Nếu bạn còn nhớ, chúng ta đang sử dụng là posts helper trong template postsList:

<template name="postsList">
  <div class="posts">
    {{#each posts}}
      {{> postItem}}
    {{/each}}
  </div>
</template>

Với việc định nghĩa helper posts, điều đó có nghĩa là chúng ta có thể sử dụng cho template, do đó template của chúng ta sẽ có thể lặp qua mảng postData và đưa vào mỗi object tương ứng template postItem.

The domain Helper Tương tự như vậy, chúng ta sẽ tạo post_item.js để giữ logic của template postItem: client/templates/posts/post_item.js

Template.postItem.helpers({
  domain: function() {
    var a = document.createElement('a');
    a.href = this.url;
    return a.hostname;
  }
});

Lần này giá trị domain helper của chúng tôi không phải là một mảng, nhưng một chức năng vô danh. Mô hình này là phổ biến hơn nhiều (và hữu dụng hơn) so với trước đây được đơn giản hóa ví dụ dữ liệu giả của chúng tôi. Helper domain nhận một URL và trả về domain thông qua JavaScript. Nhưng ngay từ ban đầu, từ đâu nó có thể nhận url? Để trả lời câu hỏi này, chúng ta cần phải quay lại template posts_list.html. Block helper {{#each}}không chỉ lặp lại trên mảng, mà nó còn thiết lập giá trị của this bên trong block vào object lặp tương ứng. Điều này có nghĩa là giữa hai tag {{#each}}, mỗi bài viết được gán vàothis lần lượt, và điều đó mở rộng tất cả mọi thứ bên trong trình quản lý template (post_item.js). Bây giờ chúng ta đã hiểu tại sao this.url trả về URL của bài viết hiện tại. Hơn thế nữa, nếu chúng ta dùng {{title}} và {{url}}bên trong template post_item, Meteor biết được rằng chúng ta muốn chỉ this.title và this.url và trả về giá trị đúng đắn. Nếu bạn đã theo dõi xuyên suốt hướng dẫn, bạn sẽ thấy được một danh sách bài viết trong trình duyệt. Danh sách đó đơn giản chỉ là dữ liệu tĩnh, vì vậy mà nó không sử dụng tính năng real-time của Meteor. Và chúng ta sẽ biết cách làm điều này trong chương kế tiếp!

Nguồn tham khảo: https://www.meteor.com/tutorials/blaze/templates https://github.com/DiscoverMeteor/Microscope/commit/chapter3-1


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí