Theo như tutorial Angular-Meteor mà chúng ta sẽ bám theo thì trong bài viết này mình sẽ trình bày về 3 mục con đầu tiên là Bootstrapping, Static Template và Dynamic Template. Về Bootstrap thì đây là một khái niệm rất quen thuộc cho những ai đã làm việc với Angular, với những người mới thì khi thấy Bootstrap có thể có một chút nhầm lẫn với framework Bootstrap trong lập trình HTML, CSS và JS (lập trình UI) nên mình cũng xin nhấn mạnh trước là khái niệm Bootstrap trong Angular không liên quan gì tới framework Bootstrap trong lập trình HTML, CSS, JS. Và cụ thể hơn chúng ta sẽ đi vào phần nội dung bài viết với mục lục như sau:
- Chuẩn bị môi trường lập trình: cài đặt Meteor, thêm Angular 2 và Typescript vào project.
- Angular 2: Root Component và Template.
- Bootstrapping: Chạy thử ứng dụng.
1. Chuẩn bị môi trường lập trình:

Đầu tiên thứ chắc chắn chúng ta cần phải có đó là Meteor và Angular 2. Và, bắt đầu bằng việc cài đặt Meteor. Mình khuyến khích các bạn sử dụng hệ điều hành linux trong quá trình làm việc, tuy nhiên các bạn cũng có thể sử dụng Windows nhưng theo mình thấy thì tốc độ khởi động ứng dụng có vẻ chậm hơn và hơn nữa là lâu lâu lại gặp những lỗi xung đột các kiểu :3.. Nên tốt hơn vẫn là linux và cũng là hệ điều hành mà rất nhiều lập trình viên sử dụng:
- Cài đặt trên linux, OSX:
curl https://install.meteor.com | sh
- Cài đặt trên Windows:
Để cài đặt trên Windows, các bạn có thể tải về và cài đặt tại đây.
Để tiện hơn cho các bạn trong quá trình lập trình thì mình sẽ liệt kê ra một số câu lệnh sử dụng với Meteor mà các bạn sẽ thường xuyên sử dungj:
- Tạo project Meteor:
meteor create
, ví dụ:meteor create first-meteor-app
. Về việc đặt tên cho project thì các ràng buộc về tên project cũng tương tự như ràng buộc đặt tên cho thư mục hoặc tên file file. - Để start app thì các bạn chỉ cần gõ:
meteor
tại ví trí thư mục project. App sẽ khởi động và khi khởi động xong các bạn có thể mở trình duyệt và truy cập:localhost:3000
. Đây là port mặc định của Meteor, các bạn cũng có thể dùng port khác bằng cách chạy dòng lệnh:meteor run -p xxxx
với xxxx chính là giá trị port mà các bạn muốn ứng dụng lắng nghe trên port đó. - Cài đặt Meteor package từ https://atmospherejs.com/ các bạn tìm package cần dùng ở trên này và cài đặt bằng cách gõ:
meteor add
, ví dụ:meteor add accounts-password
để cài package quản lý người dùng của Meteor. Để xem các package Meteor mà các bạn đã cài đặt các bạn có thể xem tại file :.meteor/packages
(trong thư mục project nhé các bạn keke). - Cài đặt NPM package, các bạn có thể tìm các package cần dùng ở đây https://www.npmjs.com/ tương tự như khi code NodeJS, và cú pháp nó sẽ dài hơn 1 tí xíu là:
meteor npm install --save
, việc thêm cờ –save vào nhằm mục đích lưu package vừa thêm vào file package.json ở trong mục dependences, để khi push code lên github repo hay những cái khác, các bạn không cần push thư mục node_modules và khi người khác pull mã nguồn của các bạn về thì chỉ cần gõmeteor npm install
thì tự động nó sẽ download các node_module dựa theo file package.json. - Reset project, khi các bạn cảm thấy bấn loạn khi dữ liệu tạm trong quá trình làm việc nó nhiều quá và chắc hẳn bạn sẽ không đi xóa từng phần 1, mà thay vào đó bạn có thể dùng
meteor reset
, để reset lại ứng dụng. (Có vài trường hợp bạn không biết bug nó nằm ở đâu thì cứ mạnh tay reset nếu không còn cần database hiện tại nữa 😀 :D.. Đôi khi reset xong nó lại chạy đấy, dev mà :v :v..).
Như vậy là cơ bản chúng ta đã cài đặt xong Meteor. Các bạn không cần phải quan tâm về node/npm hay là MongoDB nữa, vì Meteor đã thêm sẵn vào rồi, việc còn lại chỉ là dùng thôi 😀 :D.. Tuy nhiên, trong tương lai, khi deploy project thì cũng đòi hỏi các bạn phải cài MongoDB tách riêng với app, với mục đích an toàn chứ cũng không có gì hơn, và tới khi đó mình sẽ có bài về cài MongoDB và deploy project cho các bạn.
Angular 2 và Typescript

Với Angular 2 và Typescript thì cả 2 đều là thư viện Node, tức là các bạn có thể cài đặt từ npm, với ứng dụng Angular – Meteor thì tutorial mà chúng ta follow có cung cấp cho chúng ta 1 file packages.json
chứa các package Angular 2, Typescript, và một số package sẽ sử dụng cho sau này. Trước hết chúng ta sẽ sử dụng json này luôn và cụ thể về từng package mình sẽ trình bày khi gặp package đó trong quá trình chia sẻ.
Trong Angular 2 – Meteor app chúng ta có thể sử dụng Javascript (ES5), Javascript bản mới nhất (ES2015 aka ES6) và Typescript. Tuy nhiên team phát triển Angular khuyên (recommend) chúng ta sử dụng Typescript và theo như tutorial thì chúng ta cũng sử dụng Typescript để làm việc. Các bạn không cần lo lắng vì mình chưa biết về Typescript, vì cú pháp của nó cũng tương tự như Javascript (ES5, ES6) chỉ có thêm một số khái niệm trong hướng đối tượng, và có check kiểu dữ liệu cho biến, những thứ cần trong quá trình làm thì khi gặp mình sẽ trình bày luôn. Cũng khuyến cáo các bạn nên tìm hiểu sâu để việc áp dụng được linh hoạt hơn nhé, các bạn có thể tìm hiểu thêm về Typescript Typescript Tutorial.
Chúng ta cũng phải cấu hình typescript để nó biên dịch theo hướng chúng ta muốn, và trong tutorial cũng đã chứa file config phù hợp, một cái mình cũng đề cập về Typescript đó chính là việc Typescript sinh ra cũng nhằm mục đích compile mã nguồn ES6 về ES5 (javascript) để có thể hoạt động trên tất cả các trình duyệt vì ES6 vẫn chưa phổ biến trên mọi trình duyệt và phiên bản trình duyệt. File cấu hình đó có tên là tsconfig.json
, để biết thêm về cách thức hoạt động và tùy chỉnh compiler cho Typescript các bạn có thể xem Typescript Configuration.
Thành phần cuối cùng đó là @types
, các package @types được Microsoft phát triển cho Typescript với mục đích giúp Typescript có thể hỗ trợ cho các package được viết bằng javascript, và @types
được áp dụng cho Typescript > 2.0. chúng ta sẽ thêm những type cần thiết vào file typings.d.ts
và được tsconfig.json
load lên, chi tiết hơn về @types
các bạn có thể xem @types. * Phần này tác giả nói khá là sơ sài nên mình sẽ tìm hiểu thêm và sẽ giải thích với các bạn một cách cụ thể hơn.
Demo Angular 2 Meteor project
Đây là 1 project Demo chứa đầy đủ cách config cần thiết cho 1 ứng dụng Angular 2 Meteor. Các bạn clone code về theo cú pháp sau: git clone https://github.com/Urigo/angular2-meteor-base
. Và sau khi clone thành công thì chúng ta sẽ xóa đi phần nội dung trong các thư mục /client, /server, /both
. Giữ lại những thứ mà người ta đã config sẵn.

Về cấu trúc của ứng dụng Demo và những thứ người ta đã thêm vào các bạn có thể xem thêm Demo Angular 2 Meteor. Về nội dung của 3 thư mục mà chúng ta vừa xóa thì phần này thuộc về Meteor là chính. Thư mục client, chứa những thứ mà client có thể truy cập và sử dụng, tương tự với server thì chỉ server side mới truy cập và sử dụng được, chỉ có thư mục both, cho phép cả 2 có thể sử dụng. Trong những thư mục đó có những gì, chúng ta sẽ tiến hành thấy được trong quá trình làm. Tiếp theo chúng ta sẽ đi vào xây dựng View và tìm hiểu về vai trò cũng như vị trí của Angular 2 trong Angular 2 Meteor app.
2. Angular 2 – Component, Template:
Khởi đầu với trang index.html, chúng ta sẽ tạo 1 file index.html trong thư mục client, với nội dung:
// - /client/index.html: Vị trí đặt file <head> <base href="/"> </head> <body> Hello World! </body>
Khi start ứng dụng: gõ meteor
, thì ứng dụng sẽ start lên và sẽ tự động Refresh lại trang sau khi có thay đổi trong mã nguồn của bạn. Và truy cập vào localhost:3000
thì sẽ thấy được nội dung của file index.html. Và với Meteor, chúng ta không cần khai báo thẻ html như thông thường, mà chỉ cần thẻ head vs body như trên. Việc còn lại Meteor sẽ đi ghép hết nội dung của tất cả các file html lại với nhau.

Component
Một khái niệm mới trong lập trình front-end mà các bạn cần phải quan tâm đó chính là khái niệm Component (1 Component gồm 1 View (hiển thị) và 1 Controller(xử lý logic)), hiện nay đa số người ta sử dụng khái niệm này để xây dựng nên các framework, như React của facebook cũng sử dụng khái niệm này, và Angular cũng vậy. Trong Angular, Component được tổ chức theo dạng cây. Tức là sẽ có 1 Component gốc (Root Component), và các Component nhánh (Branch Component), với việc chia Component như vậy sẽ rất tiện trong quá trình làm việc nhóm, mình cũng nói nhỏ xíu với mấy bạn trước 1 tí là viết stylesheets (CSS) trong Component sẽ không bị override lẫn nhau, của Component nào thì Component đó xài, trừ trường hợp share xài chung :D..

Và chúng ta sẽ bắt đầu tạo 1 Root Component như sau. Tạo 1 file app.component.ts
trong thư mục client
với nội dung:
// - /client/imports/app/app.component.ts : Vị trí đặt file import { Component } from '@angular/core'; @Component({ selector: 'app' }) export class AppComponent {}
Đầu tiên chúng ta import Component vào để sử dụng Decorator @Component, cái Decorator này nó cũng giống như Anotation bên Java vậy, đánh dấu cho cái class ở phía dưới chính là Component, và thiết lập các meta data cho Component đó. Hiện tại đây chúng ta có 1 meta anotation đó là selector: 'app'
, selector này sẽ thực hiện select thẻ app
trong html, và render View của nó lên ngay chính thẻ đó, và chúng ta sẽ thêm thẻ đó vào sau.
Theo như trên thì Class AppComponent sẽ chính là controller xử lý logic, và còn lại phần chưa có trong Component chính là phần View. Chúng ta tiếp tục thêm 1 file nữa đó là: app.component.html
, với nội dung:
// - /client/imports/app/app.component.html : Vị trí đặt file <ul> <li> <span>Dubstep-Free Zone</span> <p> Can we please just for an evening not listen to dubstep. </p> </li> <li> <span>All dubstep all the time</span> <p> Get it on! </p> </li> </ul>
File này mình chỉ muốn đưa ra cho các bạn biết về khái niệm Static Template. Tức là trang View của chúng ta sẽ là 1 trang html tĩnh, các bạn biết html tĩnh là gì rồi đúng không, nó là tĩnh nên nó là html tĩnh đó mà :D.. Quay trở lại vấn đề chính, khi xây dựng 1 ứng dụng web thì hẳn “rất ít” người dùng các trang tĩnh để hiển thị dữ liệu, mà thay vào đó là người ta dùng trang động (Dynamic Template) để thực hiện công việc này. Trang động -> hiển thị dữ liệu động -> dữ liệu động ở đâu ra? Để trả lời câu hỏi này thì chúng ta phải quay lại với Component, Component chứa View, nên hiểu một cách con nít thì View có thể truy cập tới dữ liệu trong Component. Ôi, nó đúng thật là như vậy, Component có Controller xử lý logic trên dữ liệu (class AppComponent), View hiển thị dữ liệu sau khi đã xử lý (app.component.html). Chuẩn rồi phải không nào các bạn :D.. Thật ra Component chỉ là gói Model-View-Controller lại làm 1, hiện tại chưa có Model nhưng an tâm, nó sẽ sớm xuất hiện :D..
Component – Controller
Chém gió dài quá rồi, công việc tiếp theo của chúng ta sẽ là tạo dữ liệu trong controller, class trong ES6 có hỗ trợ cho chúng ta phương thức khởi tạo (constructor) và chúng ta sẽ dùng nó để khởi tạo dữ liệu demo. Sau khi thêm data vào thì file app.component.ts
sẽ như sau:
// - /client/imports/app/app.component.ts : Vị trí đặt file import { Component } from '@angular/core'; @Component({ selector: 'app' }) export class AppComponent { parties: anyp[]; constructor() { this.parties = [ {'name': 'Dubstep-Free Zone', 'description': 'Can we please just for an evening not listen to dubstep.', 'location': 'Palo Alto' }, {'name': 'All dubstep all the time', 'description': 'Get it on!', 'location': 'Palo Alto' }, {'name': 'Savage lounging', 'description': 'Leisure suit required. And only fiercest manners.', 'location': 'San Francisco' } ]; } }
Đôi lời tâm sự về cái file app.component.ts
này:
parties: any[];
: Dòng này thuộc về Typescript 😀 :D.. Mục đích là khai báo thuộc tính trong class, và định kiểu dữ liệu cho nó, trong trường hợp nào chúng ta đã tạo 1 thuộc tình parties cho class AppComponent và kiểu dữ liệu của nó là 1 mảng các phần tử có kiểu dữ liệu bất kỳ.this
context: Các thuộc tính khi được truy cập trong class đều phải sử dụng con trỏ this. Về con trỏ this thì các bạn có thể xem thêm bài sử dụng con trỏ this sao cho đúng.
Component – View
Data đã có, việc còn lại là sử dụng Angular tạo View cho Component này. À, quên mất một điều là những thứ này giờ mình nói là của Angular nhé 😀 :D.. Mình sẽ nói cái nào của cái nào luôn cho các bạn cover được 2 cái cùng lúc. OK. Bây giờ sẽ là Angular 2 View. File app.component.html
của chúng ta bây giờ sẽ có:
<div> <ul> <li> {{party.name}} {{party.description}} {{party.location}} </li> </ul> </div>
Từ View truy cập vào dữ liệu trong Component bằng tên của biến trong Component. Như ví dụ trên chúng ta dùng biến parties trong Component. Và thực hiện lặp để render ra cho người dùng. Trong file html trên chúng ta sử dụng một số thành phần trong Angular 2. Cụ thể là: *ngFor, cặp ngoặc nhọn {{}}. Trong Angular 2, một khái niệm đi trước Component chính là Directive, ngFor chính là 1 Directive, thực hiện lặp trên mảng dữ liệu và render ra cho người dùng, trong ví dụ trên chúng ta sẽ duyệt trong mảng parties, và render từng thẻ li tương ứng (parties có 3 phần tử trong mảng thì chúng ta có 3 phần tử li).
Để sử dụng Directive *ngFor này thì chúng ta phải thêm 1 số thành phần cần dùng và mình sẽ nhắc lại trong phần Bootstrap. Còn với cặp {{}} thì Angular 2 dùng cái này để hiển thị dữ liệu, tương tự như các Expresstion trong những công nghệ lập trình Web khác.
Và chúng ta sẽ thêm file html này vào trong Component bằng các bước:
- Từ file Component, import file html vào template.
- Thêm meta anotation
template
để cho Component xác định được Template.
Kết quả file app.component.ts
sẽ có thay đổi và:
// - /client/imports/app/app.component.ts : Vị trí đặt file import { Component } from '@angular/core'; import template from './app.component.html'; @Component({ selector: 'app', template }) export class AppComponent { parties: any[]; constructor() { this.parties = [ {'name': 'Dubstep-Free Zone', 'description': 'Can we please just for an evening not listen to dubstep.', 'location': 'Palo Alto' }, {'name': 'All dubstep all the time', 'description': 'Get it on!', 'location': 'Palo Alto' }, {'name': 'Savage lounging', 'description': 'Leisure suit required. And only fiercest manners.', 'location': 'San Francisco' } ]; } }
Trước khi release phiên bản chính thức, thì Angular 2 sử dụng templateUrl thay cho template như bây giờ, thì điểm khác biệt nằm ở cách thức load file html lên, và cuối cùng thì người ta chọn cách import html như 1 String như cách mà chúng ta đang làm. Và các bạn cũng có thể thử với templateUrl để có một chút so sánh giữa 2 cái này.
Vậy là chúng ta đã tạo xong AppComponent, tuy nhiên có vẻ như app vẫn chưa hoạt động như cách chúng ta muốn mà vẫn còn kết quả Hello World! trước đó, cái chúng ta muốn đó là trình duyệt sẽ hiển thị thẻ h1 mà chúng ta để trong template của Root Component. Và để làm được điều đó chúng ta sẽ phải Bootstrap để khởi động Angular và đạt được kết quả hiển thị như chúng ta đang muốn.
3. Bootstrapping:
Để bootstrap AppComponent và gắn nó là root component, chúng ta sẽ phải thực hiện các bước sau:
- Thêm thẻ
app
vào file index.html, để Component select và render template vào thẻ này. - Tạo Angular Module để khai báo các Module cần thiết và quan trọng nhất là khai báo Component chúng ta vừa định nghĩa.
- Bootstrap module để khởi động ứng dụng.
Add app
element:
File index.html trong thư mục client sẽ như sau:
// - /client/index.html : Vị trí đặt file <head> <base href="/"> </head> <body> <app></app> </body>
Mục đích đặt thẻ này trong thẻ body như trên để khi Component được bootstrap thì selector của Component sẽ select thẻ app lên và render template bỏ vào trong thẻ này. Selector này cũng có nét giống như là CSS selector, select cái thẻ và xử lý trên nó.
Tạo Module
Trong Angular 2, khái niệm Module được đưa ra với mục đích dùng nó vào việc đóng gói các Component, Directive, Pipe… và thêm các Module khác vào để sử dụng. Các bạn có thể đọc thêm về NgModule.
Chúng ta sẽ tạo AppModule trong thư mục app:
// - /client/imports/app/app.module.ts : Vị trí đặt file import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; @NgModule({ imports: [ BrowserModule ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) export class AppModule {}
Vì file AppComponent cùng mức với AppModule. Nên khi AppComponent được export thì chúng ta chỉ cần import nó vào Module với cú pháp import như trên. Có 2 điều đáng để chú ý trong đoạn code trên, 1 là BrowserModule, việc xây dựng Module như chúng ta đang làm là để gom các thành phần có liên quan lại làm 1. BrowserModule thì người ta cũng làm điều tương tự, nhóm phát triển đã gom một số Directive hoặc một số các thành phần khác vào BrowserModule, đơn cử đó chính là *ngFor và *ngIf, là 2 Directive sử dụng nhiều nhất trong lập trình template. Như vậy là chúng ta đã thêm BrowserModule vào Module của chúng ta để các Component con có thể sử dụng.
Tiếp theo chúng ta sẽ khai báo Component mà chúng ta đã định nghĩa trước đó (AppComponent) trong Module bằng từ khóa declarations như trên, các bạn có thể khai báo Component, Directive, … Những thứ các bạn muốn nó dùng được trong Module thì khai báo tại thẻ này.
Và cuối cùng, chúng ta bootstrap AppComponent để nó trở thành Root Component. (Chúng ta chỉ có 1 Root Component thôi nhé) và các Component con sẽ nằm trong declarations nếu có, chứ không được nằm trong thuộc tính bootstrap. Ok. Như vậy là chúng ta đã xong phần Module.
Bootstrap Module
Chúng ta sẽ tạo 1 file trong thư mục client, vì chúng ta muốn nó được load lên khi Meteor khởi động project. Tạo file main.ts trong thư mục client:
import 'angular2-meteor-polyfills'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './imports/app/app.module'; const platform = platformBrowserDynamic(); platform.bootstrapModule(AppModule);
Về công dụng thì package angular2-meteor-polyfills
nó bao gồm Zones và Reflect-Metadata, Zones để tự động cập nhật lại View khi cần. Đây cũng là một lợi thế của Angular 2 hay hơn so với Angular 1. Và cái còn lại với mục đích: cho phép nhúng các phụ thuộc (Dependence Injection) thông qua Decorator.
2 dòng code tạo platformBrowserDynamic() và dùng nó để bootstrap module AppModule mà chúng ta đã định nghĩa ở trên và.. bùm. Gõ meteor
trong terminal để start app và tận hưởng kết quả trên trình duyệt web.
Tổng kết
Trên đây là mình đã trình bày về cách thiết lập môi trường lập trình Angular 2 Meteor và một số vấn đề liên quan, bên cạnh đó mình cũng đã trình bày sơ qua về một số thành phần chính khi xây dựng ứng dụng Angular 2 Meteor. Thì đến đây mình xin được tổng kết lại những chủ đề quan trọng trong bài viết này:
- Chuẩn bị môi trường lập trình: Cài đặt Meteor, thêm các package Angular 2, Typescript để sử dụng trong khi phát triển ứng dụng. Một số câu lệnh thường xuyên sử dụng trong Meteor.
- Tiếp theo mình đã giới thiệu về phần thêm Angular và Typescript vào và cũng đề cập đến 1 số khái niệm của từng cái. Cùng với đó là việc sử dụng khái niệm Component trong Angular để xây dựng ứng dụng Angular 2 Meteor, tạo Component, sử dụng các Directive trong Angular 2 (*ngFor, ngIf), xây dựng template sử dụng các Directive xây dựng sẵn (build-in) như trên và truy cập dữ liệu trong Component (class Component mà chúng ta còn gọi là Controller).
- Cuối cùng là phần khởi chạy ứng dụng, như mình đã trình bày thì các Component, Directive, Pipe… liên quan tới nhau đều được bao bởi 1 Module, như ví dụ chính là AppComponent, Directive ngFor, ngIf đều được bao trong AppModule. Việc import Module có sẵn cũng khá là quan trọng như trong trường hợp trên module BrowserModule có export ra Directive ngFor và ngIf nên chúng ta phải import trong AppModule để AppComponent có thể sử dụng (hoặc sau này những Component được khai báo (declarations) trong AppModule cũng có thể sử dụng). Mình nói export thôi vì thực chất 2 Directive ngFor ngIf không được định nghĩa trong BrowserModule, mà là ở trong CommonModule. Người ta định nghĩa BrowserModule -> import CommomModule vào -> export mấy cái Directive đó ra. Cái này các bạn cũng nên biết để sau này mình gặp mình sẽ dễ nhận ra trong nhiều trường hợp.
Như vậy là chúng ta đã hoàn thành bài kế tiếp trong series bài viết về Angular 2 Meteor. Các bạn hãy tiếp tục comment góp ý dưới bài viết để mình có thể cải thiện, chỉnh sửa và bổ sung để mọi người cùng thảo luận và đưa ra thông tin chính xác nhất nhé.
Hồ Quốc Toản
Tài liệu tham khảo
[1]. https://www.angular-meteor.com/tutorials/socially/angular2/bootstrapping
[2]. https://docs.angularjs.org/guide/bootstrap
[3]. https://daveceddia.com/angular-2-dependencies-overview/
Dễ hiểu đới, lời văn dí dỏm nữa, haha
Lót dép hóng bài sau 😀
LikeLike