<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Saysua Blog</title>
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="http://saysua.com/"/>
  <updated>2017-03-27T08:58:07.000Z</updated>
  <id>http://saysua.com/</id>
  
  <author>
    <name>Thach Nguyen</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Download file bằng Restangular và FileSaver</title>
    <link href="http://saysua.com/2017/03/27/download-file-bang-restangular-va-filesaver-js/"/>
    <id>http://saysua.com/2017/03/27/download-file-bang-restangular-va-filesaver-js/</id>
    <published>2017-03-27T08:41:00.000Z</published>
    <updated>2017-03-27T08:58:07.000Z</updated>
    
    <content type="html"><![CDATA[<p>Mình cần viết chức năng download có API đã được xây dựng trước để tải file bằng phương thức <code>POST</code>. Ở client mình dùng <code>Restangular</code>. Như các bạn biết thì dùng <code>Restangular</code> ta chỉ có thể đọc được dữ liệu chứ không lưu nó thành dạng file được. Sau một hồi tìm kiếm, mình tìm được thư viện <a href="https://github.com/eligrey/FileSaver.js/" target="_blank" rel="external">FileSaver.js</a> giúp ta lưu file từ <code>javascript</code>.</p>
<p>Đây là kết quả trả về từ server khi ta gọi API:</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">POST /api/download</div><div class="line"></div><div class="line"></div><div class="line"><span class="section">Request Headers:</span></div><div class="line">----------------</div><div class="line"></div><div class="line">Authorization: Bearer .... (Server của mình yêu cầu token này để xác thực user)</div><div class="line"></div><div class="line"><span class="section">Response Header:</span></div><div class="line">----------------</div><div class="line">Content-Type: application/vnd.ms-excel</div><div class="line">Content-Disposition: attachement; filename=report.xls</div></pre></td></tr></table></figure>
<p>Đây là đoạn code mình xử lý để gọi đến API và lưu data trả về thành file trên máy tính:</p>
<figure class="highlight qml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">var</span> DownloadRestangular = Restangular.withConfig(<span class="function"><span class="keyword">function</span>(<span class="params">RestangularConfigurer</span>) </span>&#123;</div><div class="line">  RestangularConfigurer.setFullResponse(<span class="literal">true</span>);</div><div class="line">&#125;);</div><div class="line"></div><div class="line">DownloadRestangular.all(<span class="built_in">url</span>)</div><div class="line">.withHttpConfig(&#123;<span class="attribute">responseType</span>: <span class="string">'arraybuffer'</span>&#125;)</div><div class="line">.post(postValue, params)</div><div class="line">.then(<span class="function"><span class="keyword">function</span>(<span class="params">res</span>) </span>&#123;</div><div class="line">    <span class="built_in">var</span> filename = res.headers(<span class="string">'Content-Disposition'</span>).match(<span class="regexp">/filename=(.*)/</span>)[<span class="number">1</span>];</div><div class="line">    <span class="built_in">var</span> file = <span class="keyword">new</span> Blob([res.data], &#123; <span class="attribute">type</span>: res.headers(<span class="string">'Content-Type'</span>) &#125;);</div><div class="line">    saveAs(file, filename);</div><div class="line">&#125;);</div></pre></td></tr></table></figure>
<p>Trước tiên, ta cần cài đặt <code>setFullResponse</code> cho <code>Restangular</code> để lấy được thông tin <code>headers</code> từ đó ta mới có <code>file type</code> và <code>file name</code>. </p>
<p>Sau đó ta cần <code>response</code> trả về kiểu <code>arraybuffer</code> như vậy ta mới dùng được với thư viện <code>FileSaver.js</code>.</p>
<p>Cuối cùng là chuyển dữ liệu trả về sang <code>Blob</code> và lưu lại bằng hàm <code>saveAs</code> của <code>FileSaver</code>.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Mình cần viết chức năng download có API đã được xây dựng trước để tải file bằng phương thức &lt;code&gt;POST&lt;/code&gt;. Ở client mình dùng &lt;code&gt;R
    
    </summary>
    
    
      <category term="Angularjs" scheme="http://saysua.com/tags/Angularjs/"/>
    
  </entry>
  
  <entry>
    <title>Kỷ luật là tự do</title>
    <link href="http://saysua.com/2017/02/08/ky-luat-la-tu-do/"/>
    <id>http://saysua.com/2017/02/08/ky-luat-la-tu-do/</id>
    <published>2017-02-08T07:35:00.000Z</published>
    <updated>2017-02-08T14:13:07.000Z</updated>
    
    <content type="html"><![CDATA[<p>Như vậy là sau khoảng 2 tháng rưỡi tham gia khóa học Machine Learning trên Coursera, ngay tối ngày hôm qua, mình đã hoàn thành xong khóa học và nhận được chứng chỉ. Đây chỉ là chứng chỉ để ghi nhận rằng mình đã hoàn thành hết khóa học, coi hết videos, làm hết các bài quiz, và hoàn thành hết các bài tập code, chứ không phải ghi nhận rằng mình đã nắm vững kiến thức về machine learning, bởi vì muốn nắm vững còn phải làm nhiều và tìm hiểu nhiều.</p>
<p>Tuy nhiên, cảm giác khi thấy thông báo chúc mừng hiện lên, được nghe những lời tổng kết của thầy <code>Andrew Ng</code>, thấy háo hứng, thú vị và phấn khích. Bởi vì đây là lần đầu sau bao lâu mình mới hoàn thành một điều gì đó khi đã theo đuổi nó trong một thời gian dài.</p>
<p>Tại sao lại như vậy?</p>
<p>Đây là những khóa học mình đã đăng ký tham gia trước đó.</p>
<p><img src="/images/coursera-courses.png" alt="courses"></p>
<p>Cả 10 khóa mà chẳng hoàn thành được một khóa nào, khóa cao nhất chỉ hoàn thành được gần 50%. Đó là do cái tính của mình, cái tính khi bắt đầu thì rất hứng thú, nhưng dần dần lại lười đi. Nên có nhiều dự định, cứ bắt đầu rồi âm thầm kết thúc. Để rồi, một thời gian sau nhìn lại mình lại cảm thấy tiếc, thấy bức rứt, thấy xấu hổ với bản thân vì đã không theo đuổi được đến cùng (theo như cái bài nào đó mình mới đọc, thì đó là bản thân mình đã trở thành nô lệ của lười nhác, khi phải gánh chịu những cảm xúc tiêu cực về bản thân). Không biết bạn nào đã từng có cảm giác như mình không.</p>
<p>Đến với khóa học Machine Learning lần này, mình đã áp dụng một phương pháp, để đưa bản thân vào khuôn khổ hơn (ít nhất là với khóa học này). Mình in ra một tờ lịch năm trên tờ giấy A4 để đánh dấu lại những ngày nào mình học, ngày nào không học, cứ mỗi tối mình kiểm tra lại và cập nhật lại tờ lịch.</p>
<p>Đây là, những ngày học và không học của mình:</p>
<p><img src="/images/lich1.jpg" alt="Lich 1"></p>
<p><img src="/images/lich2.jpg" alt="Lich 2"></p>
<p>Mỗi lần nhìn lên tờ lịch này, mình sẽ biết được mình đã học ngày nào, đã bỏ ngày nào và quan trong nhất nhìn những ngày bị đánh dấu [X] cái cảm giác nó khó chịu lắm. Vì thế mình càng hạn chế dấu X càng tốt.</p>
<p>Một cái nữa, mình dán tờ lịch ngay chỗ làm nên ngày nào nó cũng đập vào mắt mình, nhắc nhở mình, cho nên nhiều khi đi nhậu về, hơi mệt mệt định nghỉ rồi mà nghĩ đến phải đánh dấu X vào ngày đó cũng không đành, nên cố gắng ngồi học một chút cho đúng tiến độ, mặc dù ngày hôm sau vẫn phải coi lại bài đã qua. Nhưng như vậy nó cũng có tác dụng thúc ép mình phải tiếp tục ngay cả khi cảm thấy không hứng thú, cho đến khi nào hoàn thành thì thôi.</p>
<p>Và đây là kết quả của mình sau bao nhiêu cố gắng chiến đấu với bệnh lười của bản thân để thỏa mãn ham muốn tìm hiểu của mình.</p>
<p><img src="/images/coursera-ml.png" alt="Coursera-ML"></p>
<p>Một cảm giác thật tuyệt!</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Như vậy là sau khoảng 2 tháng rưỡi tham gia khóa học Machine Learning trên Coursera, ngay tối ngày hôm qua, mình đã hoàn thành xong khóa 
    
    </summary>
    
    
      <category term="Life" scheme="http://saysua.com/tags/Life/"/>
    
  </entry>
  
  <entry>
    <title>Những chức năng mới của ES6</title>
    <link href="http://saysua.com/2016/12/17/nhung-chuc-nang-moi-cua-es6/"/>
    <id>http://saysua.com/2016/12/17/nhung-chuc-nang-moi-cua-es6/</id>
    <published>2016-12-17T16:18:00.000Z</published>
    <updated>2016-12-17T16:18:21.871Z</updated>
    
    <content type="html"><![CDATA[<p>Phiên bản mới của Javascript đã ra đời được một thời gian rồi, mình cũng có làm qua nhưng chưa thực sự chú ý nhiều, chủ yếu vẫn viết theo kiểu cũ. Nay mình mới đọc lại một số tài liệu, hướng dẫn và tống hợp lại những chức năng thú vị của ES6.</p>
<h1 id="Template-string"><a href="#Template-string" class="headerlink" title="Template string"></a>Template string</h1><p>Với chức năng này ta có thể tạo một bản mẫu cho chuỗi cho phép ta nhúng các biểu thức vào, và cũng có thể viết trên nhiều dòng. Chú ý là ta sẽ dùng dấu ` chứ không phải dấu ‘, dấu này ở ngay dưới phím <code>Esc</code> trên bàn phím.</p>
<h2 id="Cach-dung"><a href="#Cach-dung" class="headerlink" title="Cách dùng"></a>Cách dùng</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> country = <span class="string">'vietnam'</span>;</div><div class="line"><span class="keyword">var</span> str = <span class="string">`Xin chao <span class="subst">$&#123;country&#125;</span></span></div><div class="line">phep tinh 1 + 2 = <span class="subst">$&#123;<span class="number">1</span>+<span class="number">2</span>&#125;</span>`;</div><div class="line"><span class="built_in">console</span>.log(str);</div></pre></td></tr></table></figure>
<p>Kết quả</p>
<figure class="highlight lsl"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">Xin chao vietnam</div><div class="line">phep tinh <span class="number">1</span> + <span class="number">2</span> = <span class="number">3</span></div></pre></td></tr></table></figure>
<h1 id="Destructuring-assignment-Tach-va-gan"><a href="#Destructuring-assignment-Tach-va-gan" class="headerlink" title="Destructuring assignment (Tách và gán)"></a>Destructuring assignment (Tách và gán)</h1><p><code>Tách và gán</code> là mình tự dịch ra thôi, chức năng này cho phép ta trích xuất dữ liệu từ mảng hoặc đối tượng gán vào các biến riêng lẽ.</p>
<h2 id="Cach-dung-1"><a href="#Cach-dung-1" class="headerlink" title="Cách dùng"></a>Cách dùng</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>];</div><div class="line"><span class="keyword">var</span> [one, two, three] = arr;</div><div class="line"><span class="built_in">console</span>.log(<span class="string">'one is'</span>, one);     <span class="comment">// =&gt; one is 1</span></div><div class="line"><span class="built_in">console</span>.log(<span class="string">'two is'</span>, two);     <span class="comment">// =&gt; two is 2</span></div><div class="line"><span class="built_in">console</span>.log(<span class="string">'three is'</span>, three); <span class="comment">// =&gt; three is 3</span></div><div class="line"></div><div class="line"><span class="comment">// Lấy 1 phần của mảng</span></div><div class="line"><span class="keyword">var</span> [a, ...rest] = arr;</div><div class="line"><span class="built_in">console</span>.log(a);                 <span class="comment">// =&gt; 1</span></div><div class="line"><span class="built_in">console</span>.log(rest);              <span class="comment">// =&gt; [2,3]</span></div><div class="line"></div><div class="line"><span class="keyword">var</span> obj = &#123;<span class="attr">name</span>: <span class="string">'thach'</span>, <span class="attr">age</span>: <span class="number">27</span>&#125;;</div><div class="line"><span class="keyword">var</span> &#123;name, age&#125; = obj;</div><div class="line"><span class="built_in">console</span>.log(<span class="string">'name is'</span>, name);  <span class="comment">// =&gt; name is thach</span></div><div class="line"><span class="built_in">console</span>.log(<span class="string">'age is'</span>, age);    <span class="comment">// =&gt; age is 27</span></div></pre></td></tr></table></figure>
<h2 id="Lay-ket-qua-tra-ve-tu-ham"><a href="#Lay-ket-qua-tra-ve-tu-ham" class="headerlink" title="Lấy kết quả trả về từ hàm"></a>Lấy kết quả trả về từ hàm</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">getTop2</span>(<span class="params"></span>) </span>&#123;</div><div class="line">    <span class="keyword">return</span> [<span class="string">'hai'</span>, <span class="string">'ha'</span>];</div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> [p1, p2] = getTop2();</div><div class="line"><span class="built_in">console</span>.log(p1);    <span class="comment">// hai</span></div><div class="line"><span class="built_in">console</span>.log(p2);    <span class="comment">// ha</span></div></pre></td></tr></table></figure>
<h2 id="Gan-cho-mot-bien-khac-ten-voi-thuoc-tinh-cua-doi-tuong"><a href="#Gan-cho-mot-bien-khac-ten-voi-thuoc-tinh-cua-doi-tuong" class="headerlink" title="Gán cho một biến khác tên với thuộc tính của đổi tượng"></a>Gán cho một biến khác tên với thuộc tính của đổi tượng</h2><figure class="highlight excel"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">var</span> obj = &#123;<span class="built_in">na</span><span class="symbol">me:</span> 'thach', a<span class="symbol">ge:</span> <span class="number">27</span>&#125;;</div><div class="line"><span class="built_in">var</span> &#123;<span class="built_in">na</span><span class="symbol">me:</span> <span class="built_in">n</span>, a<span class="symbol">ge:</span> a&#125; = obj;</div><div class="line">console.log(<span class="built_in">n</span>, a);      // thach <span class="number">27</span></div></pre></td></tr></table></figure>
<h1 id="Block-scope-voi-let"><a href="#Block-scope-voi-let" class="headerlink" title="Block scope với let"></a>Block scope với let</h1><p><code>let</code> cho phép ta tạo ra một biến được giới hạn trong phạm vi của block chứa nó. <code>let</code> khác với <code>var</code> ở chỗ, <code>var</code> tạo ra một biến có phạm vi toàn cục hoặc xuyên suốt một hàm. Để rõ hơn thì mình coi qua ví dụ so sánh giữa <code>let</code> và <code>var</code>.</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">if</span> (<span class="literal">true</span>) &#123;</div><div class="line">    <span class="comment">// Đây là 1 block của if</span></div><div class="line">  <span class="keyword">var</span> a = <span class="string">'foo'</span>;</div><div class="line">  <span class="keyword">let</span> b = <span class="string">'bar'</span>;</div><div class="line">  <span class="built_in">console</span>.log(a);       <span class="comment">// foo</span></div><div class="line">  <span class="built_in">console</span>.log(b);       <span class="comment">// bar</span></div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(a);         <span class="comment">// foo</span></div><div class="line"><span class="built_in">console</span>.log(b);         <span class="comment">// Error: Uncaught ReferenceError: b is not defined</span></div></pre></td></tr></table></figure>
<p>Như ta thấy ở ví dụ trên, biến <code>b</code> chỉ có thể dùng trong if-block mà không thể dùng bên ngoài được. Bây giờ ta tiếp tục ví dụ với hàm.</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">varFunc</span>(<span class="params"></span>) </span>&#123;</div><div class="line">  <span class="keyword">var</span> x = <span class="number">1</span>;</div><div class="line">  <span class="keyword">if</span> (<span class="literal">true</span>) &#123;</div><div class="line">    <span class="keyword">var</span> x = <span class="number">2</span>;</div><div class="line">    <span class="built_in">console</span>.log(x);         <span class="comment">// 2</span></div><div class="line">  &#125;</div><div class="line">  <span class="built_in">console</span>.log(x);           <span class="comment">// 2</span></div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">letFunc</span>(<span class="params"></span>) </span>&#123;</div><div class="line">  <span class="keyword">let</span> y = <span class="number">1</span>;</div><div class="line">  <span class="keyword">if</span> (<span class="literal">true</span>) &#123;</div><div class="line">    <span class="keyword">let</span> y = <span class="number">2</span>;</div><div class="line">    <span class="built_in">console</span>.log(y);         <span class="comment">// 2</span></div><div class="line">  &#125;</div><div class="line">  <span class="built_in">console</span>.log(y);           <span class="comment">// 1  </span></div><div class="line">&#125;</div><div class="line"></div><div class="line">varFunc();</div><div class="line">letFunc();</div></pre></td></tr></table></figure>
<p>Khi ta <code>let y = 2</code>  bên trong if-block nó tạo ra một biến <code>y</code> mới không liên quan gì đến <code>let y = 1</code> ở trên cả. cho nên sau if-block, <code>y</code> bên ngoài không bị thay đổi.</p>
<h2 id="Dung-let-voi-bat-dong-bo"><a href="#Dung-let-voi-bat-dong-bo" class="headerlink" title="Dùng let với bất đồng bộ"></a>Dùng let với bất đồng bộ</h2><p>Hãy xem ví dụ sau:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; <span class="number">3</span>; i ++) &#123;</div><div class="line">  setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</div><div class="line">    <span class="built_in">console</span>.log(<span class="string">'var'</span>, i);</div><div class="line">  &#125;);</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="comment">// var 3</span></div><div class="line"><span class="comment">// var 3</span></div><div class="line"><span class="comment">// var 3         </span></div><div class="line"></div><div class="line"><span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; <span class="number">3</span>; i ++) &#123;</div><div class="line">  setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</div><div class="line">    <span class="built_in">console</span>.log(<span class="string">'var'</span>, i);</div><div class="line">  &#125;);</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="comment">// var 0</span></div><div class="line"><span class="comment">// var 1</span></div><div class="line"><span class="comment">// var 2</span></div></pre></td></tr></table></figure>
<p>Nếu ta dùng <code>var</code> ở trên, sau khi 3 vòng lặp thực hiện xong, 3 dòng <code>console.log</code> bên trong <code>setTimeout</code> sẽ được thực thi, khi đó in ra giá trị <code>i</code> lúc này đã là <code>3</code> rồi, cho nên ta có 3 nội dung <code>var 3</code> giống nhau.</p>
<p>Tuy nhiên nếu dùng <code>let</code> như ở dưới, mỗi vòng lặp tạo ra một biến <code>i</code> không liên quan gì đến nhau, cho nên ta có 3 nội dung in ra khác nhau.</p>
<p>Vì vậy, ta thấy dùng <code>let</code> sẽ giúp cho code rõ ràng hơn trong trường hợp này, tránh phải sai lầm không mong muốn.</p>
<h2 id="Const"><a href="#Const" class="headerlink" title="Const"></a>Const</h2><p>Coi về <code>let</code> rồi thì tranh thủ coi về <code>const</code> 1 chút luôn. <code>const</code> giúp ta định nghĩa một biến với giá trị không thể thay đổi.</p>
<figure class="highlight vhdl"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">const a = <span class="symbol">'foo</span>';</div><div class="line">a = <span class="symbol">'bar</span>';     // <span class="literal">Error</span>: Uncaught TypeError: Assignment <span class="keyword">to</span> <span class="keyword">constant</span> <span class="keyword">variable</span>.</div></pre></td></tr></table></figure>
<h1 id="Class"><a href="#Class" class="headerlink" title="Class"></a>Class</h1><p>Khi trước để tạo một giả <code>class</code> trong js ta sẽ dùng <code>function</code>, như thế này:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Person</span>(<span class="params"></span>) </span>&#123;</div><div class="line">    <span class="comment">// ....</span></div><div class="line">&#125;</div><div class="line"></div><div class="line">Person.prototype.hello = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</div><div class="line">    <span class="built_in">console</span>.log(<span class="string">'hello'</span>);</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">var</span> p1 = <span class="keyword">new</span> Person();</div><div class="line">p1.hello();     <span class="comment">// hello</span></div></pre></td></tr></table></figure>
<p>Nay với ES6, ta có <code>class</code>, giúp ta có thể tạo lớp, đối tượng, làm việc với kế thừa một cách đơn giản hơn.</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span> </span>&#123;</div><div class="line">    <span class="keyword">constructor</span> (name) &#123;</div><div class="line">    <span class="keyword">this</span>.name = name;</div><div class="line">  &#125;</div><div class="line">  </div><div class="line">  speak() &#123;</div><div class="line">    <span class="built_in">console</span>.log(<span class="string">'My name is'</span>, <span class="keyword">this</span>.name);</div><div class="line">  &#125;</div><div class="line">  </div><div class="line">  <span class="comment">// static method có thể được gọi mà không cần đến đối tượng của class</span></div><div class="line">  <span class="keyword">static</span> sayHello() &#123;</div><div class="line">    <span class="built_in">console</span>.log(<span class="string">'Hello'</span>);</div><div class="line">  &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">var</span> p1 = <span class="keyword">new</span> Person(<span class="string">'Viet'</span>);</div><div class="line">p1.speak();                 <span class="comment">// My name is Viet</span></div><div class="line"></div><div class="line">Person.sayHello();          <span class="comment">// Hello</span></div></pre></td></tr></table></figure>
<h2 id="Tao-mot-class-con-voi-extends"><a href="#Tao-mot-class-con-voi-extends" class="headerlink" title="Tạo một class con với extends"></a>Tạo một class con với extends</h2><p>Để tạo một class con của một class ta dùng <code>extends</code>.</p>
<figure class="highlight scala"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">Teacher</span> <span class="keyword">extends</span> <span class="title">Person</span> </span>&#123;</div><div class="line">  speak() &#123;</div><div class="line">    console.log(<span class="symbol">'My</span> name is', <span class="keyword">this</span>.name, <span class="symbol">'I</span> am a teacher');</div><div class="line">  &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">var</span> p2 = <span class="keyword">new</span> <span class="type">Teacher</span>(<span class="symbol">'Ha</span>i');</div><div class="line">p2.speak();     <span class="comment">// My name is Hai I am a teacher</span></div></pre></td></tr></table></figure>
<p>Nếu trong lớp con có <code>constructor</code> thì ta phải gọi phương thức <code>super()</code> trước khi sử dụng <code>this</code>.</p>
<figure class="highlight scala"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">Student</span> <span class="keyword">extends</span> <span class="title">Person</span> </span>&#123;</div><div class="line">  constructor(name, school) &#123;</div><div class="line">    <span class="keyword">super</span>(name);</div><div class="line">    <span class="keyword">this</span>.school = school;</div><div class="line">  &#125;</div><div class="line">  </div><div class="line">  speak() &#123;</div><div class="line">    console.log(<span class="symbol">'My</span> name is', <span class="keyword">this</span>.name, <span class="symbol">'I</span> am studying in', <span class="keyword">this</span>.school);</div><div class="line">  &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">var</span> p3 = <span class="keyword">new</span> <span class="type">Student</span>(<span class="symbol">'Min</span>h', <span class="symbol">'S</span>T');</div><div class="line">p3.speak();     <span class="comment">// My name is Minh I am studying in ST</span></div></pre></td></tr></table></figure>
<h1 id="Arrow-functions"><a href="#Arrow-functions" class="headerlink" title="Arrow functions"></a>Arrow functions</h1><p>Một cách viết hàm mới, ngắn gọn hơn.</p>
<p>Dưới đây là ví dụ so sánh giữa cách viết cũ và mới.</p>
<figure class="highlight lsl"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="comment">// ES5</span></div><div class="line">[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>].map(function (num) &#123; return num * <span class="number">2</span>; &#125;)</div><div class="line"><span class="comment">// =&gt; [2, 4, 6]</span></div><div class="line"></div><div class="line"><span class="comment">// ES6</span></div><div class="line">[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>].map((num) =&gt; &#123; return num * <span class="number">2</span>; &#125;)</div><div class="line"><span class="comment">// =&gt; [2, 4, 6]</span></div><div class="line"></div><div class="line"><span class="comment">// Vì chỉ có 1 tham số num nên ta có thể bỏ dấu ngoặc đơn luôn</span></div><div class="line">[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>].map(num =&gt; &#123; return num * <span class="number">2</span>; &#125;)</div><div class="line"><span class="comment">// =&gt; [2, 4, 6]</span></div><div class="line"></div><div class="line"><span class="comment">// Nhưng ở đây cũng chỉ có mỗi lệnh return nên ta có thể bỏ luôn dấu ngoặc nhọn và return</span></div><div class="line">[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>].map(num =&gt; num * <span class="number">2</span>)</div><div class="line"><span class="comment">// =&gt; [2, 4, 6]</span></div></pre></td></tr></table></figure>
<p>Nếu như hàm có nhiều tham số, và có nhiều dòng lệnh hơn thì ta viết đầy đủ thế này:</p>
<figure class="highlight dart"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>].map((<span class="built_in">num</span>, index) =&gt; &#123;</div><div class="line">  console.log(index);</div><div class="line">  <span class="keyword">return</span> <span class="built_in">num</span> * <span class="number">2</span>;  </div><div class="line">&#125;);</div><div class="line"><span class="comment">// 0</span></div><div class="line"><span class="comment">// 1</span></div><div class="line"><span class="comment">// 2</span></div><div class="line"><span class="comment">// =&gt; [2, 4, 6]</span></div></pre></td></tr></table></figure>
<h2 id="Tra-ve-mot-object"><a href="#Tra-ve-mot-object" class="headerlink" title="Trả về một object"></a>Trả về một object</h2><p>Chú ý nếu muốn trả về một object ta không chỉ đơn giản dùng <code>{ key: value }</code> được.</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> func1 = <span class="function"><span class="params">()</span> =&gt;</span> &#123; <span class="attr">name</span>: <span class="string">'saysua'</span> &#125;;</div><div class="line">func1(); <span class="comment">// undefined</span></div><div class="line"></div><div class="line"><span class="keyword">var</span> func2 = <span class="function"><span class="params">()</span> =&gt;</span> &#123; <span class="attr">name</span>: <span class="string">'saysua'</span>, <span class="attr">age</span>: <span class="number">3</span> &#125;;</div><div class="line">func2(); <span class="comment">// Error: Uncaught SyntaxError</span></div></pre></td></tr></table></figure>
<p>Lỗi ở đây là do, ở giữa cặp dấu ngoặc nhọn <code>{}</code> code sẽ được hiểu là một chuỗi các câu lệnh. Như ở <code>func1</code>, <code>name</code> được hiểu là 1 <code>label</code> chứ không phải là một <code>key</code> của object. (<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label" target="_blank" rel="external">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label</a>)</p>
<p>Ta viết lại cho đúng như sau:</p>
<figure class="highlight gcode"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">var fu<span class="symbol">nc1</span> = <span class="comment">()</span> =&gt; <span class="comment">(&#123; name: 'saysua' &#125;)</span>;</div><div class="line">fu<span class="symbol">nc1</span><span class="comment">()</span>; <span class="comment">// =&gt; Object &#123;name: "saysua"&#125;</span></div><div class="line"></div><div class="line">var fu<span class="symbol">nc2</span> = <span class="comment">()</span> =&gt; <span class="comment">(&#123; name: 'saysua', age: 3 &#125;)</span>;</div><div class="line">fu<span class="symbol">nc2</span><span class="comment">()</span>; <span class="comment">// =&gt; Object &#123;name: "saysua", age: 3&#125;</span></div></pre></td></tr></table></figure>
<h2 id="Arrow-function-khong-tu-dong-bind-this"><a href="#Arrow-function-khong-tu-dong-bind-this" class="headerlink" title="Arrow function không tự động bind this"></a>Arrow function không tự động bind this</h2><p>Nếu ở ES5 ta tạo một hàm mới, nó sẽ luôn tự tạo ra một giá trị <code>this</code> vì vậy code dưới đây sẽ chạy bị sai.</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Runner</span>(<span class="params"></span>) </span>&#123;</div><div class="line">  <span class="keyword">this</span>.count = <span class="number">1</span>;</div><div class="line">  setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</div><div class="line">    <span class="keyword">this</span>.count ++;  <span class="comment">//  this ở đây không phải là this ở trên nên this.count không tồn tại</span></div><div class="line">    <span class="built_in">console</span>.log(<span class="keyword">this</span>.count);  <span class="comment">// NaN</span></div><div class="line">  &#125;, <span class="number">100</span>);</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">var</span> r = <span class="keyword">new</span> Runner();</div></pre></td></tr></table></figure>
<p>Ta sẽ thường xử lý bằng cách gán một biến <code>that = this</code> hoặc là <code>bind(this)</code> vào hàm bên trong.</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Runner</span>(<span class="params"></span>) </span>&#123;</div><div class="line">  <span class="keyword">var</span> that = <span class="keyword">this</span>;</div><div class="line"></div><div class="line">  <span class="keyword">this</span>.count = <span class="number">1</span>;</div><div class="line">  setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</div><div class="line">    that.count ++;</div><div class="line">    <span class="built_in">console</span>.log(that.count);  <span class="comment">// 2</span></div><div class="line">  &#125;, <span class="number">100</span>);</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">var</span> r = <span class="keyword">new</span> Runner();</div></pre></td></tr></table></figure>
<p>Còn arrow function không tự động tạo giá trị <code>this</code> nên đoạn code sau sẽ chạy đúng như ta mong muốn.</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Runner</span>(<span class="params"></span>) </span>&#123; </div><div class="line">  <span class="keyword">this</span>.count = <span class="number">1</span>;</div><div class="line">  setTimeout(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</div><div class="line">    <span class="keyword">this</span>.count ++;</div><div class="line">    <span class="built_in">console</span>.log(<span class="keyword">this</span>.count);  <span class="comment">// 2</span></div><div class="line">  &#125;, <span class="number">100</span>);</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">var</span> r = <span class="keyword">new</span> Runner();</div></pre></td></tr></table></figure>
<p>Tuy nhiên, chính vì đặc tính này mà bạn cần phải chú ý khi sử dụng arrow function trong một số trường hợp, ví dụ:</p>
<figure class="highlight coffeescript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">var sum = &#123;</div><div class="line">  a: <span class="number">1</span>,</div><div class="line">  b: <span class="number">2</span>,</div><div class="line">  run: <span class="function"><span class="params">()</span> =&gt;</span> &#123;</div><div class="line">    <span class="built_in">console</span>.log(<span class="keyword">this</span> === <span class="built_in">window</span>); <span class="regexp">//</span> =&gt; <span class="literal">true</span> (<span class="keyword">this</span> không phải là sum)</div><div class="line">    <span class="keyword">return</span> <span class="keyword">this</span>.a + <span class="keyword">this</span>.b; <span class="regexp">//</span> NaN (nên <span class="keyword">this</span>.a và <span class="keyword">this</span>.b không có)</div><div class="line">  &#125;</div><div class="line">&#125;; </div><div class="line"></div><div class="line">sum.run();</div></pre></td></tr></table></figure>
<h1 id="Tong-ket"><a href="#Tong-ket" class="headerlink" title="Tổng kết"></a>Tổng kết</h1><p>Mình thấy những tính năng mới của ES6 rất thú vị, giúp viết code nhanh và vui hơn, vẫn còn nhiều tính năng mới nữa nhưng mình chưa tìm hiểu hết được. Tuy nhiên một vài trường hợp cần phải sử dụng cẩn thận, kẻo nhanh quá lại hóa sai, không kiểm soát được các giá trị. Happy codding!</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Phiên bản mới của Javascript đã ra đời được một thời gian rồi, mình cũng có làm qua nhưng chưa thực sự chú ý nhiều, chủ yếu vẫn viết theo
    
    </summary>
    
    
      <category term="Javascript" scheme="http://saysua.com/tags/Javascript/"/>
    
  </entry>
  
  <entry>
    <title>Lưu log của nginx vào elastic search bằng logstash</title>
    <link href="http://saysua.com/2016/12/04/push-nginx-log-to-elasticsearch-by-using-logstash/"/>
    <id>http://saysua.com/2016/12/04/push-nginx-log-to-elasticsearch-by-using-logstash/</id>
    <published>2016-12-04T08:00:00.000Z</published>
    <updated>2016-12-04T08:34:00.708Z</updated>
    
    <content type="html"><![CDATA[<p>Thông thường, mỗi truy cập vào nginx đều được lưu vào file log, ví dụ <code>/var/log/nginx/access.log</code>. Tại đây, ta có thể coi các thông tin về truy cập như thời gian, đường dẫn, trình duyệt của người dùng.</p>
<p>Nhưng nếu ta cần có thống kê chi tiết hơn về các truy cập này, như số lượt truy cập trong ngày, phân loại người dùng … thì file log này là chưa đủ. Cho nên, ta có thể đẩy những log này lên elastic search rồi từ đó dùng các công cụ thích hợp để phân tích.</p>
<a id="more"></a>
<p>Dưới đây là các bước mình đẩy log của nginx lên elastic search sử dụng logstash.</p>
<h1 id="Cai-dat-elastic-search-va-logstash"><a href="#Cai-dat-elastic-search-va-logstash" class="headerlink" title="Cài đặt elastic search và logstash"></a>Cài đặt elastic search và logstash</h1><p>Môi trường mình sử dụng ở đây là ubuntu, coi như nginx đã được cài đặt rồi.</p>
<ul>
<li>Cài đặt elastic search theo hướng dẫn sau: <a href="https://www.elastic.co/guide/en/elasticsearch/reference/5.0/deb.html" target="_blank" rel="external">https://www.elastic.co/guide/en/elasticsearch/reference/5.0/deb.html</a></li>
<li>Cài đặt logstash theo hướng dẫn sau: <a href="https://www.elastic.co/guide/en/logstash/current/installing-logstash.html#package-repositories" target="_blank" rel="external">https://www.elastic.co/guide/en/logstash/current/installing-logstash.html#package-repositories</a></li>
</ul>
<p><em>Chú ý: Phiên bản elastic search hiện tại yêu cầu java 1.8</em></p>
<h1 id="Start-elastic-search-va-logstash"><a href="#Start-elastic-search-va-logstash" class="headerlink" title="Start elastic search và logstash"></a>Start elastic search và logstash</h1><p>Từ terminal để khởi động hai dịch vụ trên ta chạy:</p>
<figure class="highlight crmsh"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">sudo service elasticsearch <span class="literal">start</span></div><div class="line">sudo service logstash <span class="literal">start</span></div></pre></td></tr></table></figure>
<h1 id="Ban-log-cua-nginx"><a href="#Ban-log-cua-nginx" class="headerlink" title="Bản log của nginx"></a>Bản log của nginx</h1><p>Dưói đây là một mẫu log của nginx</p>
<figure class="highlight accesslog"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="number">192.168.1.100</span> - - <span class="string">[01/Dec/2016:10:38:17 +0700]</span> <span class="string">"<span class="keyword">GET</span> / HTTP/1.1"</span> <span class="number">304</span> <span class="number">0</span> <span class="string">"-"</span> <span class="string">"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"</span></div></pre></td></tr></table></figure>
<h1 id="Tao-1-pattern-cho-logstash-de-phan-tich-mau-log-cua-nginx"><a href="#Tao-1-pattern-cho-logstash-de-phan-tich-mau-log-cua-nginx" class="headerlink" title="Tạo 1 pattern cho logstash để phân tích mẫu log của nginx"></a>Tạo 1 pattern cho logstash để phân tích mẫu log của nginx</h1><p>Trong thư mục <code>/usr/share/logstash/</code> tạo thư mục <code>patterns</code>, sau đó tạo file <code>nginx</code> (Chú ý là file, chứ không phải thư mục) trong thư mục <code>patterns</code></p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">sudo nano <span class="regexp">/usr/</span>share<span class="regexp">/logstash/</span>patterns<span class="regexp">/nginx</span></div></pre></td></tr></table></figure>
<p>Nội dung file <code>nginx</code> như sau:</p>
<figure class="highlight dust"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="xml">NGINX_ACCESS %</span><span class="template-variable">&#123;IPORHOST:remote_ip&#125;</span><span class="xml"> - %</span><span class="template-variable">&#123;DATA:user_name&#125;</span><span class="xml"> \[%</span><span class="template-variable">&#123;HTTPDATE:time&#125;</span><span class="xml">\] "%</span><span class="template-variable">&#123;WORD:request_action&#125;</span><span class="xml"> %</span><span class="template-variable">&#123;DATA:request&#125;</span><span class="xml"> HTTP/%</span><span class="template-variable">&#123;NUMBER:http_version&#125;</span><span class="xml">" %</span><span class="template-variable">&#123;NUMBER:response&#125;</span><span class="xml"> %</span><span class="template-variable">&#123;NUMBER:bytes&#125;</span><span class="xml"> "%</span><span class="template-variable">&#123;DATA:referrer&#125;</span><span class="xml">" "%</span><span class="template-variable">&#123;DATA:agent&#125;</span><span class="xml">"</span></div></pre></td></tr></table></figure>
<h1 id="Cau-hinh-logstash-de-day-log-tu-nginx-len-elastic-search"><a href="#Cau-hinh-logstash-de-day-log-tu-nginx-len-elastic-search" class="headerlink" title="Cấu hình logstash để đẩy log từ nginx lên elastic search"></a>Cấu hình logstash để đẩy log từ nginx lên elastic search</h1><p>Tạo file <code>nginx.conf</code> trong thư mục <code>/etc/logstash/conf.d/</code></p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">sudo nano <span class="regexp">/etc/</span>logstash<span class="regexp">/conf.d/</span>nginx.conf</div></pre></td></tr></table></figure>
<p>Nội dung file <code>nginx.conf</code> như sau:</p>
<figure class="highlight puppet"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">input</span> &#123;</div><div class="line">  file &#123;</div><div class="line">    <span class="attr">type</span> =&gt; <span class="string">"nginx"</span></div><div class="line">    <span class="attr">start_position</span> =&gt; <span class="string">"beginning"</span></div><div class="line">    <span class="attr">path</span> =&gt; [ <span class="string">"/var/log/nginx/*.log"</span> ]</div><div class="line">  &#125;</div><div class="line">&#125;</div><div class="line"><span class="keyword">filter</span> &#123;</div><div class="line">  <span class="keyword">if</span> [<span class="built_in">type</span>] == <span class="string">"nginx"</span> &#123;</div><div class="line">    grok &#123;</div><div class="line">        <span class="attr">patterns_dir</span> =&gt; <span class="string">"/usr/share/logstash/patterns"</span></div><div class="line">        <span class="attr">match</span> =&gt; &#123; <span class="string">"message"</span> =&gt; <span class="string">"%&#123;NGINX_ACCESS&#125;"</span> &#125;</div><div class="line">        <span class="keyword">remove_tag</span> =&gt; [<span class="string">"_grokparsefailure"</span>]</div><div class="line">        add_tag =&gt; [<span class="string">"nginx_access"</span>]</div><div class="line">    &#125;</div><div class="line">    <span class="keyword">date</span> &#123;</div><div class="line">      <span class="attr">match</span> =&gt; [ <span class="string">"time"</span>, <span class="string">"dd/MMM/YYYY:HH:mm:ss Z"</span> ]</div><div class="line">      <span class="attr">locale</span> =&gt; en</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="keyword">geoip</span> &#123;</div><div class="line">      <span class="attr">source</span> =&gt; <span class="string">"remote_ip"</span></div><div class="line">      <span class="attr">target</span> =&gt; <span class="string">"geoip"</span></div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="keyword">useragent</span> &#123;</div><div class="line">      <span class="attr">source</span> =&gt; <span class="string">"agent"</span></div><div class="line">      <span class="attr">target</span> =&gt; <span class="string">"user_agent"</span></div><div class="line">    &#125;</div><div class="line">  &#125;</div><div class="line">&#125;</div><div class="line"><span class="keyword">output</span> &#123;</div><div class="line">  elasticsearch &#123;</div><div class="line">    <span class="attr">index</span> =&gt; <span class="string">"nginx_log_test"</span></div><div class="line">    <span class="attr">hosts</span> =&gt; [<span class="string">"localhost:9200"</span>] </div><div class="line">  &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h1 id="Config-lai-quyen-cua-file-log-de-logstash-co-the-doc-duoc"><a href="#Config-lai-quyen-cua-file-log-de-logstash-co-the-doc-duoc" class="headerlink" title="Config lại quyền của file log để logstash có thể đọc được"></a>Config lại quyền của file log để logstash có thể đọc được</h1><figure class="highlight excel"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">chmod <span class="number">644</span> /<span class="built_in">var</span>/<span class="built_in">log</span>/nginx/*.<span class="built_in">log</span></div></pre></td></tr></table></figure>
<h1 id="Ket-qua"><a href="#Ket-qua" class="headerlink" title="Kết quả"></a>Kết quả</h1><p>Bây giờ bạn thử truy cập vào trang web được phục vụ bởi server nginx của bạn, cứ mỗi lần bạn truy cập vào thì log của nginx sẽ được logstash đẩy lên elastic search.</p>
<p>Đây là kết quả khi mình search từ elastic search tại đường dẫn <code>http://192.168.1.244:9200/nginx_log_test/_search?&amp;scroll=1m&amp;size=1000&amp;pretty=true</code></p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div></pre></td><td class="code"><pre><div class="line">&#123;</div><div class="line">  <span class="attr">"_scroll_id"</span> : <span class="string">"DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAAdFkhleEZWRFdPUmJXcnBqc3h0eUtGbWcAAAAAAAAAHBZIZXhGVkRXT1JiV3JwanN4dHlLRm1nAAAAAAAAABoWSGV4RlZEV09SYldycGpzeHR5S0ZtZwAAAAAAAAAeFkhleEZWRFdPUmJXcnBqc3h0eUtGbWcAAAAAAAAAGxZIZXhGVkRXT1JiV3JwanN4dHlLRm1n"</span>,</div><div class="line">  <span class="attr">"took"</span> : <span class="number">3</span>,</div><div class="line">  <span class="attr">"timed_out"</span> : <span class="literal">false</span>,</div><div class="line">  <span class="attr">"_shards"</span> : &#123;</div><div class="line">    <span class="attr">"total"</span> : <span class="number">5</span>,</div><div class="line">    <span class="attr">"successful"</span> : <span class="number">5</span>,</div><div class="line">    <span class="attr">"failed"</span> : <span class="number">0</span></div><div class="line">  &#125;,</div><div class="line">  <span class="attr">"hits"</span> : &#123;</div><div class="line">    <span class="attr">"total"</span> : <span class="number">1</span>,</div><div class="line">    <span class="attr">"max_score"</span> : <span class="number">1.0</span>,</div><div class="line">    <span class="attr">"hits"</span> : [</div><div class="line">      &#123;</div><div class="line">        <span class="attr">"_index"</span> : <span class="string">"nginx_log_test"</span>,</div><div class="line">        <span class="attr">"_type"</span> : <span class="string">"nginx"</span>,</div><div class="line">        <span class="attr">"_id"</span> : <span class="string">"AVi4dhUNQ4OVFTpBmGks"</span>,</div><div class="line">        <span class="attr">"_score"</span> : <span class="number">1.0</span>,</div><div class="line">        <span class="attr">"_source"</span> : &#123;</div><div class="line">          <span class="attr">"request"</span> : <span class="string">"/"</span>,</div><div class="line">          <span class="attr">"request_action"</span> : <span class="string">"GET"</span>,</div><div class="line">          <span class="attr">"agent"</span> : <span class="string">"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"</span>,</div><div class="line">          <span class="attr">"geoip"</span> : &#123; &#125;,</div><div class="line">          <span class="attr">"user_name"</span> : <span class="string">"-"</span>,</div><div class="line">          <span class="attr">"http_version"</span> : <span class="string">"1.1"</span>,</div><div class="line">          <span class="attr">"message"</span> : <span class="string">"192.168.1.100 - - [01/Dec/2016:10:38:14 +0700] \"GET / HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36\""</span>,</div><div class="line">          <span class="attr">"type"</span> : <span class="string">"nginx"</span>,</div><div class="line">          <span class="attr">"tags"</span> : [</div><div class="line">            <span class="string">"nginx_access"</span>,</div><div class="line">            <span class="string">"_geoip_lookup_failure"</span></div><div class="line">          ],</div><div class="line">          <span class="attr">"path"</span> : <span class="string">"/var/log/nginx/access.log"</span>,</div><div class="line">          <span class="attr">"referrer"</span> : <span class="string">"-"</span>,</div><div class="line">          <span class="attr">"@timestamp"</span> : <span class="string">"2016-12-01T03:38:14.000Z"</span>,</div><div class="line">          <span class="attr">"remote_ip"</span> : <span class="string">"192.168.1.100"</span>,</div><div class="line">          <span class="attr">"response"</span> : <span class="string">"304"</span>,</div><div class="line">          <span class="attr">"bytes"</span> : <span class="string">"0"</span>,</div><div class="line">          <span class="attr">"@version"</span> : <span class="string">"1"</span>,</div><div class="line">          <span class="attr">"host"</span> : <span class="string">"ubuntu"</span>,</div><div class="line">          <span class="attr">"time"</span> : <span class="string">"01/Dec/2016:10:38:14 +0700"</span>,</div><div class="line">          <span class="attr">"user_agent"</span> : &#123;</div><div class="line">            <span class="attr">"patch"</span> : <span class="string">"2840"</span>,</div><div class="line">            <span class="attr">"os"</span> : <span class="string">"Windows 10"</span>,</div><div class="line">            <span class="attr">"major"</span> : <span class="string">"54"</span>,</div><div class="line">            <span class="attr">"minor"</span> : <span class="string">"0"</span>,</div><div class="line">            <span class="attr">"name"</span> : <span class="string">"Chrome"</span>,</div><div class="line">            <span class="attr">"os_name"</span> : <span class="string">"Windows 10"</span>,</div><div class="line">            <span class="attr">"device"</span> : <span class="string">"Other"</span></div><div class="line">          &#125;</div><div class="line">        &#125;</div><div class="line">      &#125;</div><div class="line">    ]</div><div class="line">  &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>Bạn thấy đấy, log của nginx đã được phân tách và lưu đầy đủ trên elastic search. Thật tuyệt vời phải không?</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Thông thường, mỗi truy cập vào nginx đều được lưu vào file log, ví dụ &lt;code&gt;/var/log/nginx/access.log&lt;/code&gt;. Tại đây, ta có thể coi các thông tin về truy cập như thời gian, đường dẫn, trình duyệt của người dùng.&lt;/p&gt;
&lt;p&gt;Nhưng nếu ta cần có thống kê chi tiết hơn về các truy cập này, như số lượt truy cập trong ngày, phân loại người dùng … thì file log này là chưa đủ. Cho nên, ta có thể đẩy những log này lên elastic search rồi từ đó dùng các công cụ thích hợp để phân tích.&lt;/p&gt;
    
    </summary>
    
    
      <category term="Logstash" scheme="http://saysua.com/tags/Logstash/"/>
    
      <category term="Nginx" scheme="http://saysua.com/tags/Nginx/"/>
    
      <category term="Elastic search" scheme="http://saysua.com/tags/Elastic-search/"/>
    
  </entry>
  
  <entry>
    <title>Chạy Visual Studio Solution từ command line</title>
    <link href="http://saysua.com/2016/12/01/chay-visual-studio-solution-tu-command-line/"/>
    <id>http://saysua.com/2016/12/01/chay-visual-studio-solution-tu-command-line/</id>
    <published>2016-12-01T03:10:24.000Z</published>
    <updated>2016-12-01T03:15:08.293Z</updated>
    
    <content type="html"><![CDATA[<p>Đôi khi ta muốn chạy một solution của Visual Studio từ command line thay vì phải mở Visual Studio IDE lên để giảm bớt tài nguyên cho hệ thống, ta có thể làm như sau:</p>
<ul>
<li>Di chuyển đến thư mục chứa file <code>.sln</code></li>
<li>Build code <code>&quot;C:\Program Files (x86)\MSBuild\14.0\Bin\msbuild.exe&quot; SelfHost.sln /p:Configuration=Release (Hoặc là Debug)</code></li>
<li>Chạy file đã build <code>SelfHost\bin\Release\SelfHost.exe</code></li>
</ul>
<p>Để thuận tiện cho những lần chạy sau, ta có thể tạo một file <code>bat</code>, khi nào cần chỉ cần click một phát là xong.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Đôi khi ta muốn chạy một solution của Visual Studio từ command line thay vì phải mở Visual Studio IDE lên để giảm bớt tài nguyên cho hệ t
    
    </summary>
    
    
      <category term="Visual Studio" scheme="http://saysua.com/tags/Visual-Studio/"/>
    
  </entry>
  
  <entry>
    <title>Tôi học Machine Learning - 004 - Unsupervised Learning - Học không có giám sát</title>
    <link href="http://saysua.com/2016/11/26/toi-hoc-machine-learning-004-unsupervised-learning-hoc-khong-co-giam-sat/"/>
    <id>http://saysua.com/2016/11/26/toi-hoc-machine-learning-004-unsupervised-learning-hoc-khong-co-giam-sat/</id>
    <published>2016-11-26T07:23:00.000Z</published>
    <updated>2016-11-26T07:30:33.358Z</updated>
    
    <content type="html"><![CDATA[<p><em>Bài ghi chú</em></p>
<p>Với học không có giám sát, chúng ta biết được một ít không không có ý tưởng về kết quả sẽ như thế nào. Chúng ta được đưa cho dữ liệu và yêu cầu trả về cấu trúc của dữ liệu đó dựa vào mối quan hệ giữa các biến trong dữ liệu.</p>
<p>Ví dụ:</p>
<ul>
<li>Dựa vào dữ liệu về khách hàng của một công ty, chúng ta phân nhóm khách hàng để có thể thực hiện các chiến dịch bán hàng đặc biệt.</li>
<li>Phân loại các nhóm thành viên trên mạng xã hội.</li>
<li>Trong một bữa tiệc, ta có tập ghi âm thanh, ta có thể phân tích và tách các tạp âm để lọc ra âm thanh riêng của từng người.</li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;em&gt;Bài ghi chú&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Với học không có giám sát, chúng ta biết được một ít không không có ý tưởng về kết quả sẽ như thế nào. Chúng 
    
    </summary>
    
    
      <category term="Machine Learning" scheme="http://saysua.com/tags/Machine-Learning/"/>
    
  </entry>
  
  <entry>
    <title>Tôi học Machine Learning - 003 - Supervised Learning - Học có giám sát</title>
    <link href="http://saysua.com/2016/11/25/toi-hoc-machine-learning-003-supervised-learning-hoc-co-giam-sat/"/>
    <id>http://saysua.com/2016/11/25/toi-hoc-machine-learning-003-supervised-learning-hoc-co-giam-sat/</id>
    <published>2016-11-25T07:29:00.000Z</published>
    <updated>2016-11-25T07:47:58.452Z</updated>
    
    <content type="html"><![CDATA[<p><em>Bài ghi chú</em></p>
<p>Với <code>học có giám sát (Supervised Learning)</code>, chúng ta được đưa một dữ liệu với kết quả đầu ra tương ứng đã biết trước, ta cần xây dựng mối quan hệ dữa đầu vào và đầu ra, để dự đoán kết quả đầu ra của các giá trị đầu vào khác.</p>
<p>Ví dụ, dự đoán giá nhà dựa vào vị trí, kích thước của căn nhà.</p>
<p>Học có giám sát được chia ra làm hai loại, <code>regression (hồi quy)</code> và <code>classification (phân lớp)</code>.</p>
<ul>
<li>Loại hồi quy: ta cố gắng dự đoán kết quả dưới dạng liên tục.</li>
<li>Loại phân lớp: ta cố gắng dự đoán kết quả dưới dạng rời rạc.</li>
</ul>
<p>Ví dụ:</p>
<ul>
<li>Loại hồi quy: <ul>
<li>Cho kết quả kiểm tra đầu vào một lớp học, dự đoán số học sinh lên lớp.</li>
<li>Dựa vào kích thước, màu sắc của quả dưa leo, dự đoán giá bán sản phẩm.</li>
</ul>
</li>
<li>Loại phân lớp:<ul>
<li>Dựa vào kích thước, màu sắc của quả dưa leo, dự đoán có bán được hay không?</li>
<li>Cho thông tin khách hàng, dự đoán khách hàng mua sản phẩm hay không?</li>
</ul>
</li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;em&gt;Bài ghi chú&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Với &lt;code&gt;học có giám sát (Supervised Learning)&lt;/code&gt;, chúng ta được đưa một dữ liệu với kết quả đầu ra tươn
    
    </summary>
    
    
      <category term="Machine Learning" scheme="http://saysua.com/tags/Machine-Learning/"/>
    
  </entry>
  
  <entry>
    <title>Tôi học Machine Learning - 002 - Khóa học trên Coursera</title>
    <link href="http://saysua.com/2016/11/23/toi-hoc-machine-learning-002/"/>
    <id>http://saysua.com/2016/11/23/toi-hoc-machine-learning-002/</id>
    <published>2016-11-23T01:36:00.000Z</published>
    <updated>2016-11-25T07:48:02.965Z</updated>
    
    <content type="html"><![CDATA[<p>Hôm trước, mình đăng ký khóa học trên Udemy, sau khi coi các bài học đầu tiên thấy rằng nó chưa hợp với mình. Vì mình chưa biết gì về ML cả mà mới vào đã hướng dẫn ngay code rồi, càng coi càng rối.</p>
<p>Tìm trên Coursera (mình đã học một khóa về Python trên này), có một khóa về ML do Andrew ng hướng dẫn, anh này mình thấy rất nổi tiếng về lĩnh vực ML, cấu trúc khóa học cũng rõ ràng, bắt đầu từ cơ bản.</p>
<p>Nên mình quyết định dừng việc theo dõi khóa học trên Udemy và tập trung vào khóa học trên Coursera trước (<a href="https://www.coursera.org/learn/machine-learning" target="_blank" rel="external">https://www.coursera.org/learn/machine-learning</a>). Mình có coi qua các đánh giá thì khóa này vẫn còn thiếu vài phần <code>Wish the course also covered decision trees, random forests and boosting algorithms.</code> mà mấy phần này bên Udemy có. Nên sau khi hoàn thành khóa trên Coursera mình sẽ quay lại coi bên Udemy.</p>
<p>Bạn nào mới bắt đầu tìm hiểu về ML thì có thể cùng mình học trên Coursera nhé. Có 2 tùy chọn Free hoặc trả phí (Trả phí thì sau khi hoàn thành sẽ có chứng nhận.)</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Hôm trước, mình đăng ký khóa học trên Udemy, sau khi coi các bài học đầu tiên thấy rằng nó chưa hợp với mình. Vì mình chưa biết gì về ML 
    
    </summary>
    
    
      <category term="Machine Learning" scheme="http://saysua.com/tags/Machine-Learning/"/>
    
  </entry>
  
  <entry>
    <title>Tôi học Machine Learning - 001 - Nhập môn</title>
    <link href="http://saysua.com/2016/11/18/toi-hoc-machine-learning-001-nhap-mon/"/>
    <id>http://saysua.com/2016/11/18/toi-hoc-machine-learning-001-nhap-mon/</id>
    <published>2016-11-18T13:20:00.000Z</published>
    <updated>2016-11-19T03:12:50.890Z</updated>
    
    <content type="html"><![CDATA[<p>Machine Learning vẫn còn là một thứ mới mẻ và khiến mình tò mò, cho nên hôm nay mình đã bắt đầu tham gia một khóa học về nó. Chuỗi các bài “Tôi học Machine Learning” là những ghi chú của mình, chứ không phải là bài hướng dẫn, vì vậy có thể có những sai sót chủ quan trong nội dung bài viết. Nếu các bạn thấy chỗ nào sai, cứ thoải mái góp ý, điều đó sẽ rất có ý nghĩa với mình.</p>
<h1 id="Phan-mem-va-ngon-ngu"><a href="#Phan-mem-va-ngon-ngu" class="headerlink" title="Phần mềm và ngôn ngữ"></a>Phần mềm và ngôn ngữ</h1><p>Đây là các phần mềm và ngôn ngữ mình cần phải cài đặt:</p>
<ul>
<li>Python <a href="https://www.python.org/" target="_blank" rel="external">https://www.python.org/</a></li>
<li>R <a href="https://cran.r-project.org/bin/windows/base/" target="_blank" rel="external">https://cran.r-project.org/bin/windows/base/</a></li>
<li>R Studio <a href="https://www.rstudio.com/products/rstudio/download/" target="_blank" rel="external">https://www.rstudio.com/products/rstudio/download/</a></li>
<li>Anaconda <a href="https://www.continuum.io/downloads" target="_blank" rel="external">https://www.continuum.io/downloads</a></li>
</ul>
<a id="more"></a>
<p>Sau khi cài Anacoda, ta sẽ có IDE <em>spyder</em> để viết và debug python code.</p>
<p><img src="/images/spyder.png" alt="Spyder IDE"></p>
<p>Còn RStudio dĩ nhiên là để viết R code rồi.</p>
<p><img src="/images/RStudio.png" alt="RStudio"></p>
<h1 id="Tien-xu-ly-du-lieu"><a href="#Tien-xu-ly-du-lieu" class="headerlink" title="Tiền xử lý dữ liệu"></a>Tiền xử lý dữ liệu</h1><p>Đây là dữ liệu mẫu cần được xử lý <code>Data.csv</code></p>
<p><img src="/images/data-01-csv.png" alt="Data.csv"></p>
<p>Trước khi xử lý dữ liệu ta cần phải <code>sơ chế</code> nó trước.</p>
<h2 id="Xu-ly-phan-du-lieu-bi-thieu"><a href="#Xu-ly-phan-du-lieu-bi-thieu" class="headerlink" title="Xử lý phần dữ liệu bị thiếu"></a>Xử lý phần dữ liệu bị thiếu</h2><p>Ở đây, trong dữ liệu mẫu ô <code>B8</code> và <code>C6</code> bị thiếu giá trị, trong quá trình sơ chế ta có thể loại bỏ 2 hàng này đi, nhưng như vậy có thể nguy hiểm vì nó có thể chứa các giá trị quan trọng. Có một cách khác là ta sẽ lấy giá trị trung bình trong cột để áp dụng vào các ô bị thiếu.</p>
<h3 id="Code-python-su-dung-thu-vien-pandas"><a href="#Code-python-su-dung-thu-vien-pandas" class="headerlink" title="Code python sử dụng thư viện pandas:"></a>Code <code>python</code> sử dụng thư viện <code>pandas</code>:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># Import libraries</span></div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</div><div class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</div><div class="line"></div><div class="line"><span class="comment"># Import data</span></div><div class="line">dataset = pd.read_csv(<span class="string">'Data.csv'</span>)</div><div class="line">X = dataset.iloc[:, :<span class="number">-1</span>].values</div><div class="line"></div><div class="line"><span class="comment"># Missing data</span></div><div class="line"><span class="keyword">from</span> sklearn.preprocessing <span class="keyword">import</span> Imputer</div><div class="line">imputer = Imputer(missing_values=<span class="string">'NaN'</span>, strategy=<span class="string">'mean'</span>, axis=<span class="number">0</span>)</div><div class="line">imputer = imputer.fit(X[:, <span class="number">1</span>:<span class="number">3</span>])</div><div class="line">X[:, <span class="number">1</span>:<span class="number">3</span>] = imputer.transform(X[:, <span class="number">1</span>:<span class="number">3</span>])</div></pre></td></tr></table></figure>
<p>Ở dòng 8, ta lấy <code>X</code> là mảng giá trị của tất cả các hàng và tất cả các cột trừ cột cuối (<code>-1</code>). Ta có giá trị <code>X</code> như sau:</p>
<figure class="highlight prolog"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">array([[<span class="string">'France'</span>, <span class="number">44.0</span>, <span class="number">72000.0</span>],</div><div class="line">       [<span class="string">'Spain'</span>, <span class="number">27.0</span>, <span class="number">48000.0</span>],</div><div class="line">       [<span class="string">'Germany'</span>, <span class="number">30.0</span>, <span class="number">54000.0</span>],</div><div class="line">       [<span class="string">'Spain'</span>, <span class="number">38.0</span>, <span class="number">61000.0</span>],</div><div class="line">       [<span class="string">'Germany'</span>, <span class="number">40.0</span>, nan],</div><div class="line">       [<span class="string">'France'</span>, <span class="number">35.0</span>, <span class="number">58000.0</span>],</div><div class="line">       [<span class="string">'Spain'</span>, nan, <span class="number">52000.0</span>],</div><div class="line">       [<span class="string">'France'</span>, <span class="number">48.0</span>, <span class="number">79000.0</span>],</div><div class="line">       [<span class="string">'Germany'</span>, <span class="number">50.0</span>, <span class="number">83000.0</span>],</div><div class="line">       [<span class="string">'France'</span>, <span class="number">37.0</span>, <span class="number">67000.0</span>]], dtype=object)</div></pre></td></tr></table></figure>
<p>Ở dòng 12, ta xác định các giá trị bị thiếu bằng <code>missing_values=&#39;NaN&#39;</code>, và thay thế chúng bằng giá trị trung bình <code>strategy=&#39;mean&#39;</code> của cột <code>axis=0</code>.</p>
<p>Ta sẽ áp dụng nó cho hai cột 1 và 2 của X (cột đầu tiên là 0): <code>X[:, 1:3]</code> (vì giá trị cột được xác định trong khoảng nên ta phải dùng <code>1:3</code> chứ không phải <code>1:2</code>)</p>
<p>Cuối cùng ta có <code>X</code>:</p>
<figure class="highlight prolog"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">array([[<span class="string">'France'</span>, <span class="number">44.0</span>, <span class="number">72000.0</span>],</div><div class="line">       [<span class="string">'Spain'</span>, <span class="number">27.0</span>, <span class="number">48000.0</span>],</div><div class="line">       [<span class="string">'Germany'</span>, <span class="number">30.0</span>, <span class="number">54000.0</span>],</div><div class="line">       [<span class="string">'Spain'</span>, <span class="number">38.0</span>, <span class="number">61000.0</span>],</div><div class="line">       [<span class="string">'Germany'</span>, <span class="number">40.0</span>, <span class="number">63777.77777777778</span>],</div><div class="line">       [<span class="string">'France'</span>, <span class="number">35.0</span>, <span class="number">58000.0</span>],</div><div class="line">       [<span class="string">'Spain'</span>, <span class="number">38.77777777777778</span>, <span class="number">52000.0</span>],</div><div class="line">       [<span class="string">'France'</span>, <span class="number">48.0</span>, <span class="number">79000.0</span>],</div><div class="line">       [<span class="string">'Germany'</span>, <span class="number">50.0</span>, <span class="number">83000.0</span>],</div><div class="line">       [<span class="string">'France'</span>, <span class="number">37.0</span>, <span class="number">67000.0</span>]], dtype=object)</div></pre></td></tr></table></figure>
<p>Các giá trị <code>nan</code> đã được thay thế bằng giá trị trung bình.</p>
<h3 id="Code-R"><a href="#Code-R" class="headerlink" title="Code R"></a>Code R</h3><figure class="highlight r"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># Import data</span></div><div class="line">dataset = read.csv(<span class="string">'Data.csv'</span>)</div><div class="line"></div><div class="line"><span class="comment"># Missing data handler</span></div><div class="line">dataset$Age = ifelse(is.na(dataset$Age),</div><div class="line">                     ave(dataset$Age, FUN = <span class="keyword">function</span>(x) mean(x, na.rm = <span class="literal">TRUE</span>)),</div><div class="line">                     dataset$Age</div><div class="line">                     )</div><div class="line"></div><div class="line">dataset$Salary = ifelse(is.na(dataset$Salary),</div><div class="line">                        ave(dataset$Salary, FUN = <span class="keyword">function</span>(x) mean(x, na.rm = <span class="literal">TRUE</span>)),</div><div class="line">                        dataset$Salary</div><div class="line">                        )</div></pre></td></tr></table></figure>
<p>Ở dòng 5, ta tính toán lại giá trị các ô trong cột <code>Age</code>, nếu ô không có giá trị <code>is.na(dataset$Age)</code>, ta sẽ lấy giá trị trung bình của cột <code>Age</code> bằng hàm <code>mean</code> và bỏ qua các giá trị bị thiếu <code>na.rm = TRUE</code> (dòng 6), nếu ô có giá trị thì ta giữ nguyên nó <code>dataset$Age</code> (dòng 7).</p>
<h1 id="Tong-ket"><a href="#Tong-ket" class="headerlink" title="Tổng kết"></a>Tổng kết</h1><p>Như vậy là mình đã biết cách căn bản để xử lý dữ liệu thiếu bằng cách lấp vào các giá trị trung bình bằng <code>python</code> và <code>R</code>. Khi viết code vẫn có nhiều chỗ chưa rõ, chúng ta có thể xem phần <code>help</code> của ứng dụng để hiểu thêm về các hàm.</p>
<p>Trong <code>Spyder</code> các bạn nhấn <code>Ctrl + I</code> tại một hàm để coi help của nó, trong <code>RStudio</code> thì nhấn <code>F1</code>.</p>
<p><strong>Mẹo</strong> Trong cả 2 IDE trên, để chạy từng đoạn code, ta bôi đen đoạn code và nhấn <code>Ctrl + Enter</code>.</p>
<p>Các ghi chú này được mình ghi lại khi đang tham gia khóa học tại <em>udemy</em> nếu bạn thấy thú vị có thể đăng ký để học trên đó, sẽ có nhiều giải thích chi tiết hơn (<a href="https://www.udemy.com/machinelearning" target="_blank" rel="external">https://www.udemy.com/machinelearning</a>) .</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Machine Learning vẫn còn là một thứ mới mẻ và khiến mình tò mò, cho nên hôm nay mình đã bắt đầu tham gia một khóa học về nó. Chuỗi các bài “Tôi học Machine Learning” là những ghi chú của mình, chứ không phải là bài hướng dẫn, vì vậy có thể có những sai sót chủ quan trong nội dung bài viết. Nếu các bạn thấy chỗ nào sai, cứ thoải mái góp ý, điều đó sẽ rất có ý nghĩa với mình.&lt;/p&gt;
&lt;h1 id=&quot;Phan-mem-va-ngon-ngu&quot;&gt;&lt;a href=&quot;#Phan-mem-va-ngon-ngu&quot; class=&quot;headerlink&quot; title=&quot;Phần mềm và ngôn ngữ&quot;&gt;&lt;/a&gt;Phần mềm và ngôn ngữ&lt;/h1&gt;&lt;p&gt;Đây là các phần mềm và ngôn ngữ mình cần phải cài đặt:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python &lt;a href=&quot;https://www.python.org/&quot;&gt;https://www.python.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;R &lt;a href=&quot;https://cran.r-project.org/bin/windows/base/&quot;&gt;https://cran.r-project.org/bin/windows/base/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;R Studio &lt;a href=&quot;https://www.rstudio.com/products/rstudio/download/&quot;&gt;https://www.rstudio.com/products/rstudio/download/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Anaconda &lt;a href=&quot;https://www.continuum.io/downloads&quot;&gt;https://www.continuum.io/downloads&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
    
    </summary>
    
    
      <category term="Machine Learning" scheme="http://saysua.com/tags/Machine-Learning/"/>
    
      <category term="Python" scheme="http://saysua.com/tags/Python/"/>
    
  </entry>
  
  <entry>
    <title>Cài đặt Nodejs trên Godaddy shared hosting</title>
    <link href="http://saysua.com/2016/10/18/cai-dat-nodejs-tren-godaddy-shared-hosting/"/>
    <id>http://saysua.com/2016/10/18/cai-dat-nodejs-tren-godaddy-shared-hosting/</id>
    <published>2016-10-18T13:45:10.000Z</published>
    <updated>2016-10-18T14:46:40.041Z</updated>
    
    <content type="html"><![CDATA[<p>Năm ngoái, có người cần mình deploy code nodejs trên shared hosting của Godaddy, sau một hồi tìm kiếm thì mình kết luận không thể làm được. Sau đó mình đã deploy lên Heroku.</p>
<p>Ngày hôm nay, mình nhận được một tình huống tương tự như vậy, nhưng kết quả đã khác. Đã có thể cài nodejs lên shared hosting của Godaddy. Dưới đây là các bước thực hiện.</p>
<a id="more"></a>
<h1 id="SSH-vao-server-cua-Godaddy"><a href="#SSH-vao-server-cua-Godaddy" class="headerlink" title="SSH vào server của Godaddy"></a>SSH vào server của Godaddy</h1><p>Ở đây mình cần phải có username để <code>ssh</code>. Lúc đầu mình nhầm username này với user đăng nhập vào trang quản lý của Goddady. Để có được username ssh này các bạn mở trình quản lý Cpanel của hosting lên.</p>
<p><img src="/images/godaddy-open-cpanel.png" alt="Open Godady Cpanel"></p>
<p>Sau đó vào phần <strong>FPT Accounts</strong>, các bạn nhìn vào danh sách <code>Special FPT Accounts</code> sẽ có username để ssh.</p>
<p><img src="/images/godaddy-get-ssh-user.png" alt="Get ssh username"></p>
<p>Để ssh nếu dùng windown thì ta có thể sử dụng chương trình Putty, còn ở Mac hoặc Linux thì mở terminal lên để ssh.</p>
<figure class="highlight dust"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="xml">ssh </span><span class="template-variable">&#123;username&#125;</span><span class="xml">@</span><span class="template-variable">&#123;public_ip&#125;</span><span class="xml"></span></div></pre></td></tr></table></figure>
<p>Ở đây <code>Password</code> nhập vào là password các bạn login vào Godaddy.</p>
<h1 id="Kiem-tra-xem-nodejs-da-duoc-cai-chua"><a href="#Kiem-tra-xem-nodejs-da-duoc-cai-chua" class="headerlink" title="Kiểm tra xem nodejs đã được cài chưa"></a>Kiểm tra xem nodejs đã được cài chưa</h1><p>Sau khi <code>ssh</code> vào server các bạn kiểm tra xem nodejs được cài chưa bằng cách.</p>
<figure class="highlight crmsh"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">which <span class="keyword">node</span></div><div class="line"><span class="title">which</span> npm</div><div class="line">which nvm</div></pre></td></tr></table></figure>
<p>Nếu không có thông tin gì, thì ta bắt đầu quá trình cài đặt.</p>
<h1 id="Cai-dat-nodejs-bang-nvm"><a href="#Cai-dat-nodejs-bang-nvm" class="headerlink" title="Cài đặt nodejs bằng nvm"></a>Cài đặt nodejs bằng nvm</h1><p>Để cài đặt <code>nodejs</code> không cần dùng quyền <code>sudo</code> ta sẽ sử dụng <a href="https://github.com/creationix/nvm" target="_blank" rel="external">nvm</a>.</p>
<p>Ta chạy lần lượt các lệnh sau:</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">curl -o- https:<span class="regexp">//</span>raw.githubusercontent.com<span class="regexp">/creationix/</span>nvm<span class="regexp">/v0.32.0/i</span>nstall.sh | bash</div></pre></td></tr></table></figure>
<p>Sau khi đã chạy xong ta có thể kiểm tra lại <code>nvm</code> đã được cài đặt bằng:</p>
<figure class="highlight ada"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">nvm <span class="comment">--version</span></div></pre></td></tr></table></figure>
<p>Cài đặt <code>nodejs</code> bằng <code>nvm</code>:</p>
<figure class="highlight crmsh"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">nvm install <span class="keyword">node</span><span class="title"></span></div></pre></td></tr></table></figure>
<p>Để kiểm tra <code>nodejs</code> đã được cài thành công ta chạy lệnh:</p>
<figure class="highlight crmsh"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">node</span> <span class="title">-v</span></div><div class="line">npm -v</div></pre></td></tr></table></figure>
<p>Từ đây ta có thể cài thêm <a href="https://github.com/Unitech/pm2" target="_blank" rel="external">pm2</a> để chạy các ứng dụng <code>nodejs</code> trên server mà không làm ứng dụng tắt đi khi ta thoát phiên ssh.</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm <span class="keyword">install</span> pm2 -g</div></pre></td></tr></table></figure>
<h1 id="Ket"><a href="#Ket" class="headerlink" title="Kết"></a>Kết</h1><p>Như vậy là mình đã có thể chạy nodejs trên shared hosting của Godaddy, tuy nhiên mình không chạy được ứng dụng ở cổng <code>http 80</code>. Khi mình chạy một ứng dụng ở cổng 5000 chẳng hạn. Mình cũng không thể truy cập được từ public IP. Tuy nhiên nếu mình truy cập từ localhost thì vẫn có thể được. Ví dụ:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">curl <span class="string">http:</span><span class="comment">//localhost:5000</span></div></pre></td></tr></table></figure>
<p>Ngoài ra mình thấy Godaddy cũng đang có dịch vụ NodeJS cloud. Cái này mình chưa thử, nên chưa biết thế nào. Dù sao thì chạy đưọc nodejs trên shared hosting cũng có thể giúp ích đưọc trong một vài trường hợp đặt biệt.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Năm ngoái, có người cần mình deploy code nodejs trên shared hosting của Godaddy, sau một hồi tìm kiếm thì mình kết luận không thể làm được. Sau đó mình đã deploy lên Heroku.&lt;/p&gt;
&lt;p&gt;Ngày hôm nay, mình nhận được một tình huống tương tự như vậy, nhưng kết quả đã khác. Đã có thể cài nodejs lên shared hosting của Godaddy. Dưới đây là các bước thực hiện.&lt;/p&gt;
    
    </summary>
    
    
      <category term="NodeJs" scheme="http://saysua.com/tags/NodeJs/"/>
    
      <category term="Nvm" scheme="http://saysua.com/tags/Nvm/"/>
    
      <category term="Godaddy" scheme="http://saysua.com/tags/Godaddy/"/>
    
  </entry>
  
  <entry>
    <title>TeamCity – Build agent disconnected</title>
    <link href="http://saysua.com/2016/09/07/teamcity-build-agent-disconnected/"/>
    <id>http://saysua.com/2016/09/07/teamcity-build-agent-disconnected/</id>
    <published>2016-09-06T23:49:01.000Z</published>
    <updated>2016-10-16T01:46:48.973Z</updated>
    
    <content type="html"><![CDATA[<p>Bellow is how I resolve my problem with TeamCity – Build agent disconnected.</p>
<p><img src="/images/teamcity-agent-disconnected.png" alt="TeamCity Agent Disconected"></p>
<ul>
<li>ssh to my centos agent machine.</li>
<li>Go to agent folder, in this case it is <code>BuildAgent</code></li>
<li>I tried to stop the agent by <code>bin/agent.sh stop</code> but got no luck. When I started the agent it said that <code>Build agent is already running with PID 1795</code>, so that I could not restart it.</li>
<li>KILL the process by <code>sudo kill 1795</code></li>
<li>Restart again <code>bin/agent.sh start</code><br>=&gt; It should work now.</li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Bellow is how I resolve my problem with TeamCity – Build agent disconnected.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/teamcity-agent-disconnected.png&quot; al
    
    </summary>
    
    
      <category term="TeamCity" scheme="http://saysua.com/tags/TeamCity/"/>
    
  </entry>
  
  <entry>
    <title>Nodejs Module Caching</title>
    <link href="http://saysua.com/2016/04/19/nodejs-module-cache-trying/"/>
    <id>http://saysua.com/2016/04/19/nodejs-module-cache-trying/</id>
    <published>2016-04-19T04:05:24.000Z</published>
    <updated>2016-10-16T01:42:38.566Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Nodejs-Module-Caching"><a href="#Nodejs-Module-Caching" class="headerlink" title="Nodejs Module Caching"></a>Nodejs Module Caching</h1><p>Modules are cached after the first time they are loaded. This means (among other things) that every call to require(‘foo’) will get exactly the same object returned, if it would resolve to the same file.</p>
<p>Multiple calls to require(‘foo’) may not cause the module code to be executed multiple times. This is an important feature. With it, “partially done” objects can be returned, thus allowing transitive dependencies to be loaded even when they would cause cycles.</p>
<p>If you want to have a module execute code multiple times, then export a function, and call that function.</p>
<p>(<a href="https://nodejs.org/api/modules.html#modules_caching" target="_blank" rel="external">https://nodejs.org/api/modules.html#modules_caching</a>)</p>
<a id="more"></a>
<h1 id="Trying-code"><a href="#Trying-code" class="headerlink" title="Trying code"></a>Trying code</h1><p>Let’s see bellow test code and the result:</p>
<p>A.js  </p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">var <span class="built_in">list</span> = [];</div><div class="line"></div><div class="line"><span class="keyword">module</span>.exports = &#123;</div><div class="line">  <span class="built_in">list</span>: <span class="built_in">list</span>,</div><div class="line">  name: <span class="string">'t'</span></div><div class="line">&#125;;</div></pre></td></tr></table></figure>
<p>index.js  </p>
<figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">var <span class="built_in">a1</span> = require(<span class="string">'./A'</span>)<span class="comment">;</span></div><div class="line">var <span class="built_in">a2</span> = require(<span class="string">'./A'</span>)<span class="comment">;</span></div><div class="line"></div><div class="line"><span class="built_in">a1</span>.list.push(<span class="number">1</span>)<span class="comment">;</span></div><div class="line">console.log(<span class="built_in">a1</span>.list)<span class="comment">;</span></div><div class="line">console.log(<span class="built_in">a2</span>.list)<span class="comment">;</span></div><div class="line"></div><div class="line">console.log(<span class="built_in">a2</span>.name)<span class="comment">;</span></div><div class="line">console.log(<span class="built_in">a1</span>.name)<span class="comment">;</span></div><div class="line"><span class="built_in">a1</span>.name = <span class="string">'update'</span><span class="comment">;</span></div><div class="line">console.log(<span class="built_in">a2</span>.name)<span class="comment">;</span></div><div class="line">console.log(<span class="built_in">a1</span>.name)<span class="comment">;</span></div></pre></td></tr></table></figure>
<p>Result  </p>
<figure class="highlight accesslog"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="string">[ 1 ]</span></div><div class="line"><span class="string">[ 1 ]</span></div><div class="line">t</div><div class="line">t</div><div class="line">update</div><div class="line">update</div></pre></td></tr></table></figure>
<p>So, we know <code>a1</code> and <code>a2</code> are the same object.</p>
]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;Nodejs-Module-Caching&quot;&gt;&lt;a href=&quot;#Nodejs-Module-Caching&quot; class=&quot;headerlink&quot; title=&quot;Nodejs Module Caching&quot;&gt;&lt;/a&gt;Nodejs Module Caching&lt;/h1&gt;&lt;p&gt;Modules are cached after the first time they are loaded. This means (among other things) that every call to require(‘foo’) will get exactly the same object returned, if it would resolve to the same file.&lt;/p&gt;
&lt;p&gt;Multiple calls to require(‘foo’) may not cause the module code to be executed multiple times. This is an important feature. With it, “partially done” objects can be returned, thus allowing transitive dependencies to be loaded even when they would cause cycles.&lt;/p&gt;
&lt;p&gt;If you want to have a module execute code multiple times, then export a function, and call that function.&lt;/p&gt;
&lt;p&gt;(&lt;a href=&quot;https://nodejs.org/api/modules.html#modules_caching&quot;&gt;https://nodejs.org/api/modules.html#modules_caching&lt;/a&gt;)&lt;/p&gt;
    
    </summary>
    
    
      <category term="Nodejs" scheme="http://saysua.com/tags/Nodejs/"/>
    
  </entry>
  
  <entry>
    <title>Nodejs - Request - Error socket hang up code - ECONNRESET</title>
    <link href="http://saysua.com/2016/03/01/nodejs-request-Error-socket-hang-up-code-ECONNRESET/"/>
    <id>http://saysua.com/2016/03/01/nodejs-request-Error-socket-hang-up-code-ECONNRESET/</id>
    <published>2016-03-01T04:05:24.000Z</published>
    <updated>2016-10-16T01:42:47.111Z</updated>
    
    <content type="html"><![CDATA[<p>Currently, I writing a nodejs server that I want to call external API via https. This is the code that I used.</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> request = <span class="built_in">require</span>(<span class="string">'request'</span>);</div><div class="line"><span class="keyword">var</span> userProfileUri = <span class="string">'http://test.com/API/user/profile'</span>;</div><div class="line">request.get(userProfileUri, &#123;</div><div class="line">  <span class="string">'headers'</span>: &#123;</div><div class="line">    <span class="string">'Authorization'</span>: <span class="string">'Bearer eyJ0eX'</span></div><div class="line">  &#125;,</div><div class="line">&#125;, <span class="function"><span class="keyword">function</span>(<span class="params">err, response, body</span>) </span>&#123;</div><div class="line">  <span class="built_in">console</span>.log(err);</div><div class="line">&#125;);</div></pre></td></tr></table></figure>
<p>After running this code, I waited for a minute and got this error:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">&#123; [<span class="string">Error:</span> socket hang up] <span class="string">code:</span> <span class="string">'ECONNRESET'</span> &#125;</div></pre></td></tr></table></figure>
<p>Doing for many searches via google, finally I got a solution that make my day happy. I hope that bellow solution can help you too.</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> request = <span class="built_in">require</span>(<span class="string">'request'</span>);</div><div class="line"><span class="keyword">var</span> userProfileUri = <span class="string">'http://test.com/API/user/profile'</span>;</div><div class="line">request.get(userProfileUri, &#123;</div><div class="line">  <span class="string">'headers'</span>: &#123;</div><div class="line">    <span class="string">'Authorization'</span>: <span class="string">'Bearer eyJ0eX'</span></div><div class="line">  &#125;,</div><div class="line">  <span class="attr">agentOptions</span>: &#123;</div><div class="line">    <span class="attr">secureOptions</span>: <span class="built_in">require</span>(<span class="string">'constants'</span>).SSL_OP_NO_TLSv1_2,</div><div class="line">    <span class="attr">ciphers</span>: <span class="string">'ECDHE-RSA-AES256-SHA:AES256-SHA:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM'</span>,</div><div class="line">    <span class="attr">honorCipherOrder</span>: <span class="literal">true</span></div><div class="line">  &#125;</div><div class="line">&#125;, <span class="function"><span class="keyword">function</span>(<span class="params">err, response, body</span>) </span>&#123;</div><div class="line">  <span class="built_in">console</span>.log(err);</div><div class="line">&#125;);</div></pre></td></tr></table></figure>
<p>The important part is <code>agentOptions</code>. Just add it to your <code>request</code> config.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Currently, I writing a nodejs server that I want to call external API via https. This is the code that I used.&lt;/p&gt;
&lt;figure class=&quot;highlig
    
    </summary>
    
    
      <category term="Nodejs" scheme="http://saysua.com/tags/Nodejs/"/>
    
  </entry>
  
  <entry>
    <title>Làm quen với Angular 2 - Zoo app - part 3 - Dependency Injection</title>
    <link href="http://saysua.com/2015/12/14/lam-quen-voi-angular2-zoo-app-part-3-dependency-injection/"/>
    <id>http://saysua.com/2015/12/14/lam-quen-voi-angular2-zoo-app-part-3-dependency-injection/</id>
    <published>2015-12-14T04:05:24.000Z</published>
    <updated>2016-10-16T02:45:35.935Z</updated>
    
    <content type="html"><![CDATA[<p>Trong phần này, chúng ta sẽ cùng nhau tạo một service <code>AnimalService</code> để quản lý danh sách các con vật và nhúng nó vào <code>AppComponent</code>.</p>
<p>Ta tạo file <code>animal-service.ts</code> cùng cấp với <code>app.ts</code>:</p>
<figure class="highlight scala"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line">export <span class="class"><span class="keyword">class</span> <span class="title">AnimalService</span> </span>&#123;</div><div class="line">  animals: [];</div><div class="line"></div><div class="line">  constructor() &#123;</div><div class="line">    <span class="keyword">this</span>.animals = <span class="type">ANIMALS</span>;</div><div class="line">  &#125;</div><div class="line"></div><div class="line">  getAnimals() &#123;</div><div class="line">    <span class="keyword">return</span> <span class="keyword">this</span>.animals;</div><div class="line">  &#125;</div><div class="line"></div><div class="line">  addAnimal(<span class="class"><span class="keyword">type</span></span>: <span class="type">String</span>, name: <span class="type">String</span>) &#123;</div><div class="line">    <span class="keyword">this</span>.animals.push(&#123; <span class="symbol">'typ</span>e': <span class="class"><span class="keyword">type</span>, '<span class="title">name</span>'</span>: name&#125;);</div><div class="line">  &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">var</span> <span class="type">ANIMALS</span> = [</div><div class="line">  &#123; <span class="class"><span class="keyword">type</span></span>: <span class="symbol">'Tige</span>r', name: <span class="symbol">'Bob</span>o'&#125;,</div><div class="line">  &#123; <span class="class"><span class="keyword">type</span></span>: <span class="symbol">'Do</span>g', name: <span class="symbol">'Mi</span>c'&#125;,</div><div class="line">  &#123; <span class="class"><span class="keyword">type</span></span>: <span class="symbol">'Elepha</span>n', name: <span class="symbol">'Bi</span>g'&#125;</div><div class="line">];</div></pre></td></tr></table></figure>
<a id="more"></a>
<p>Một cách đơn giản, <code>service</code> trong Angular 2 chỉ là một class bình thường. Ở đây, ta có class <code>AnimalService</code> nó có hai phương thức sẽ được sử dụng trong <code>AppComponent</code> là <code>getAnimals</code> và <code>addAnimal</code>.</p>
<p>Trong <code>AppComponent</code> ta inject <code>AnimalService</code> vào như sau:</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> &#123;AnimalService&#125; from <span class="string">'./animal-service'</span>;</div><div class="line"></div><div class="line">...</div><div class="line"><span class="meta">@Component(&#123;</span></div><div class="line">  ...</div><div class="line">&#125;)</div><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">AppComponent</span> </span>&#123;</div><div class="line">  <span class="keyword">public</span> selectedAnimal;</div><div class="line">  <span class="keyword">public</span> newAnimal = &#123;</div><div class="line">    type: <span class="string">''</span>,</div><div class="line">    name: <span class="string">''</span></div><div class="line">  &#125;</div><div class="line"></div><div class="line">  animals = [];</div><div class="line"></div><div class="line">  <span class="keyword">constructor</span>(<span class="keyword">private</span> animalService: AnimalService) &#123;</div><div class="line">    <span class="keyword">this</span>.animals = animalService.getAnimals();</div><div class="line">  &#125;</div><div class="line"></div><div class="line">  select(animal) &#123; <span class="keyword">this</span>.selectedAnimal = animal; &#125;</div><div class="line"></div><div class="line">  getSelectedClass(animal) &#123;</div><div class="line">    <span class="keyword">return</span> &#123;</div><div class="line">      <span class="string">'selected'</span>: animal === <span class="keyword">this</span>.selectedAnimal</div><div class="line">    &#125;</div><div class="line">  &#125;</div><div class="line"></div><div class="line">  onSubmit() &#123;</div><div class="line">    <span class="keyword">this</span>.animalService.addAnimal(<span class="keyword">this</span>.newAnimal.type, <span class="keyword">this</span>.newAnimal.name);</div><div class="line"></div><div class="line">    <span class="keyword">this</span>.newAnimal.type = <span class="string">''</span>;</div><div class="line">    <span class="keyword">this</span>.newAnimal.name = <span class="string">''</span>;</div><div class="line">  &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line">bootstrap(AppComponent, [AnimalService]);</div></pre></td></tr></table></figure>
<p>Trong <code>constructor</code> của <code>AppComponent</code> ta thêm vào tham số <code>animalService</code>, từ khóa <code>private</code> trước tham số sẽ báo cho TypeScript biết để tự động gán <code>animalService</code> trở thành một private member của <code>AppComponent</code>. Do đó trong hàm <code>onSubmit</code> ta có thể sử dụng <code>this.animalService</code>.</p>
<p>Angular 2 được xây dựng đi kèm với nó là <code>Dependency Injection framwork</code>, framwork này sẽ tự động nhúng một instance của <code>AnimalService</code> vào <code>AppComponent</code>. Tuy nhiên để được như vậy, ta cũng cần phải đồng thời khai báo <code>AnimalService</code> khi bootstrap App.</p>
<figure class="highlight lisp"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">bootstrap(<span class="name">AppComponent</span>, [AnimalService])<span class="comment">;</span></div></pre></td></tr></table></figure>
<h1 id="Nhung-service-vao-service"><a href="#Nhung-service-vao-service" class="headerlink" title="Nhúng service vào service"></a>Nhúng service vào service</h1><p>Nếu <code>AnimalService</code> của chúng ta cũng cần một service khác thì sao, ví dụ <code>LogService</code>. Khi đó <code>AnimalService</code> có thể như thế này:</p>
<figure class="highlight scala"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> &#123;<span class="type">Injectable</span>&#125; from <span class="symbol">'angular2</span>/angular2';</div><div class="line"><span class="keyword">import</span> &#123;<span class="type">LogService</span>&#125; from './log-service';</div><div class="line"></div><div class="line"><span class="meta">@Injectable</span>()</div><div class="line">export <span class="class"><span class="keyword">class</span> <span class="title">AnimalService</span> </span>&#123;</div><div class="line">  animals: [];</div><div class="line"></div><div class="line">  constructor(<span class="keyword">private</span> logger: <span class="type">LogService</span>) &#123;</div><div class="line">    <span class="keyword">this</span>.animals = <span class="type">ANIMALS</span>;</div><div class="line">  &#125;</div><div class="line"></div><div class="line">  getAnimals() &#123;</div><div class="line">    <span class="keyword">return</span> <span class="keyword">this</span>.animals;</div><div class="line">  &#125;</div><div class="line"></div><div class="line">  addAnimal(<span class="class"><span class="keyword">type</span></span>: <span class="type">String</span>, name: <span class="type">String</span>) &#123;</div><div class="line">    <span class="keyword">this</span>.logger.log(<span class="symbol">'Adding</span> <span class="keyword">new</span> animal.');</div><div class="line">    <span class="keyword">this</span>.animals.push(&#123; <span class="symbol">'typ</span>e': <span class="class"><span class="keyword">type</span>, '<span class="title">name</span>'</span>: name&#125;);</div><div class="line">  &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">var</span> <span class="type">ANIMALS</span> = [</div><div class="line">  &#123; <span class="class"><span class="keyword">type</span></span>: <span class="symbol">'Tige</span>r', name: <span class="symbol">'Bob</span>o'&#125;,</div><div class="line">  &#123; <span class="class"><span class="keyword">type</span></span>: <span class="symbol">'Do</span>g', name: <span class="symbol">'Mi</span>c'&#125;,</div><div class="line">  &#123; <span class="class"><span class="keyword">type</span></span>: <span class="symbol">'Elepha</span>n', name: <span class="symbol">'Bi</span>g'&#125;</div><div class="line">];</div></pre></td></tr></table></figure>
<p>Như vậy, để inject một service vào service khác, ta nhớ phải sử dụng <code>@Injectable()</code>.</p>
<h1 id="Tong-ket"><a href="#Tong-ket" class="headerlink" title="Tổng kết"></a>Tổng kết</h1><p>Trên đây là cách đơn giản để inject dependency vào Angular2. Thực tế có nhiều cách khác nhau để tạo một instance của service tùy từng mục đích mà chúng ta sẽ cùng nhau tìm hiểu trong những phần sau.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Trong phần này, chúng ta sẽ cùng nhau tạo một service &lt;code&gt;AnimalService&lt;/code&gt; để quản lý danh sách các con vật và nhúng nó vào &lt;code&gt;AppComponent&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Ta tạo file &lt;code&gt;animal-service.ts&lt;/code&gt; cùng cấp với &lt;code&gt;app.ts&lt;/code&gt;:&lt;/p&gt;
&lt;figure class=&quot;highlight scala&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;2&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;3&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;4&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;5&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;6&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;7&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;8&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;9&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;10&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;11&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;12&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;13&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;14&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;15&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;16&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;17&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;18&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;19&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;20&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;21&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;export &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;AnimalService&lt;/span&gt; &lt;/span&gt;&amp;#123;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;  animals: [];&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;  constructor() &amp;#123;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.animals = &lt;span class=&quot;type&quot;&gt;ANIMALS&lt;/span&gt;;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;  &amp;#125;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;  getAnimals() &amp;#123;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.animals;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;  &amp;#125;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;  addAnimal(&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt;&lt;/span&gt;: &lt;span class=&quot;type&quot;&gt;String&lt;/span&gt;, name: &lt;span class=&quot;type&quot;&gt;String&lt;/span&gt;) &amp;#123;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.animals.push(&amp;#123; &lt;span class=&quot;symbol&quot;&gt;&#39;typ&lt;/span&gt;e&#39;: &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt;, &#39;&lt;span class=&quot;title&quot;&gt;name&lt;/span&gt;&#39;&lt;/span&gt;: name&amp;#125;);&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;  &amp;#125;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&amp;#125;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;ANIMALS&lt;/span&gt; = [&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;  &amp;#123; &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt;&lt;/span&gt;: &lt;span class=&quot;symbol&quot;&gt;&#39;Tige&lt;/span&gt;r&#39;, name: &lt;span class=&quot;symbol&quot;&gt;&#39;Bob&lt;/span&gt;o&#39;&amp;#125;,&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;  &amp;#123; &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt;&lt;/span&gt;: &lt;span class=&quot;symbol&quot;&gt;&#39;Do&lt;/span&gt;g&#39;, name: &lt;span class=&quot;symbol&quot;&gt;&#39;Mi&lt;/span&gt;c&#39;&amp;#125;,&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;  &amp;#123; &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt;&lt;/span&gt;: &lt;span class=&quot;symbol&quot;&gt;&#39;Elepha&lt;/span&gt;n&#39;, name: &lt;span class=&quot;symbol&quot;&gt;&#39;Bi&lt;/span&gt;g&#39;&amp;#125;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;];&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
    
    </summary>
    
    
      <category term="Angular2" scheme="http://saysua.com/tags/Angular2/"/>
    
  </entry>
  
  <entry>
    <title>Làm quen với Angular 2 - Zoo app - part 2 - Form</title>
    <link href="http://saysua.com/2015/12/10/lam-quen-voi-angular2-zoo-app-part-2/"/>
    <id>http://saysua.com/2015/12/10/lam-quen-voi-angular2-zoo-app-part-2/</id>
    <published>2015-12-10T04:05:24.000Z</published>
    <updated>2016-10-16T02:45:33.399Z</updated>
    
    <content type="html"><![CDATA[<p>Ở <a href="/2015/12/04/lam-quen-voi-angular2-zoo-app-part-1/">phần 1</a> chúng ta đã sử dụng một vài directives cơ bản của Angular như NgFor, NgIf, NgClass và ta cũng biết rằng muốn sử dụng directive nào, ta phải khai báo directive đó cho Component. Tuy nhiên việc phải khai báo từng directive như vậy thật bất tiện. Để khắc phục điều đó, Angular 2 đã gộp các core directives vào một tập hợp là <code>CORE_DIRECTIVES</code> ta chỉ cần khai báo nó một lần là có thể dùng được các core directives của Angular. Trước khi vào phần 2 ta thay đổi một chút như sau:</p>
<figure class="highlight gradle"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> &#123;Component, bootstrap, CORE_DIRECTIVES, FORM_DIRECTIVES&#125; <span class="keyword">from</span> <span class="string">'angular2/angular2'</span>;</div><div class="line"></div><div class="line">...</div><div class="line">  directives: [CORE_DIRECTIVES, FORM_DIRECTIVES],</div></pre></td></tr></table></figure>
<p>Ngoài <code>CORE_DIRECTIVES</code> ra mình còn khai báo thêm <code>FORM_DIRECTIVES</code>, chắc hẳn là bạn đã đoán ra đó là tập hợp các directive dành cho Form của Angular.</p>
<a id="more"></a>
<h1 id="Tao-form"><a href="#Tao-form" class="headerlink" title="Tạo form"></a>Tạo form</h1><p>Trong Component template ta thêm vào form</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">form</span> (<span class="attr">ng-submit</span>)=<span class="string">"onSubmit()"</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">label</span>&gt;</span>Type<span class="tag">&lt;/<span class="name">lable</span>&gt;</span><span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">required</span> [(<span class="attr">ng-model</span>)]=<span class="string">"newAnimal.type"</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">label</span>&gt;</span>Name<span class="tag">&lt;/<span class="name">lable</span>&gt;</span><span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">required</span> [(<span class="attr">ng-model</span>)]=<span class="string">"newAnimal.name"</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">button</span> <span class="attr">type</span>=<span class="string">"submit"</span>&gt;</span>Add<span class="tag">&lt;/<span class="name">button</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">form</span>&gt;</span></div></pre></td></tr></table></figure>
<p>Trong Component ta thêm thuộc tính <code>newAnimal</code> và phương thức <code>onSubmit</code>:</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> newAnimal = &#123;</div><div class="line">  type: <span class="string">''</span>,</div><div class="line">  name: <span class="string">''</span></div><div class="line">&#125;</div><div class="line"></div><div class="line">onSubmit() &#123;</div><div class="line">  <span class="keyword">this</span>.animals.push(&#123;</div><div class="line">    type: <span class="keyword">this</span>.newAnimal.type,</div><div class="line">    name: <span class="keyword">this</span>.newAnimal.name</div><div class="line">  &#125;);</div><div class="line"></div><div class="line">  <span class="keyword">this</span>.newAnimal.type = <span class="string">''</span>;</div><div class="line">  <span class="keyword">this</span>.newAnimal.name = <span class="string">''</span>;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>Sau khi ta nhập thông tin vào form và nhấn nút <code>Add</code> phương thức <code>onSubmit</code> sẽ được gọi. Trong phương thức này ta push thêm một animal mới vào danh sách <code>this.animals</code> với dữ liệu được lấy từ <code>this.newAnimal</code> mà ta đã liên kết nó với form input bằng <code>[(ng-model)]</code>. Sau khi add xong, ta làm trống 2 ô text input bằng cách gán chuỗi rỗng vào <code>type</code> và <code>name</code> của <code>newAnimal</code>.</p>
<h1 id="ng-model"><a href="#ng-model" class="headerlink" title="ng-model"></a>ng-model</h1><p><em>Phần này trình bày sâu về directive ng-mode, bạn có thể bỏ qua nếu muốn dùng mà không cần tìm hiểu thêm</em></p>
<p>Như ta thấy ở trên, dữ liệu giữa model và text input đã được truyền theo kiểu two-way data binding.</p>
<p>Với Property binding, <code>ng-model</code> được bọc trong cặp dấu <code>[]</code>, khi dữ liệu của model thay đổi, nó sẽ thay đổi phần view của text input. Cho nên khi ta gán <code>this.newAnimal.type = &#39;&#39;</code>, text input của ta cũng bị làm rỗng. Dữ liệu ở đây đi theo chiều <strong>model -&gt; view</strong>.</p>
<p>Với Event binding, <code>ng-model</code> được bọc trong cặp dấu <code>()</code>, khi giá trị của text input thay đổi, dữ liệu sẽ được cập nhật lại vào trong <code>newAnimal</code>. Chính vì vậy, khi form được submit ta mới có thể lấy được thông tin nhập vào từ text input. Dữ liệu ở đây đi theo chiều <strong>view -&gt; model</strong>.</p>
<p>Thực tế thì ta có thể tách <code>[(ngModel)]</code> ra 2 phần riêng lẽ như sau:</p>
<figure class="highlight vim"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">&lt;<span class="built_in">input</span> <span class="built_in">type</span>=<span class="string">"text"</span> required (ng-model-<span class="keyword">change</span>)=<span class="string">"newAnimal.type = $event"</span> [ng-model]=<span class="string">"newAnimal.type"</span>&gt;</div></pre></td></tr></table></figure>
<p>Việc binding cũng sẽ diễn ra tương tự.</p>
<p><code>ng-model-change</code> ở đây không phải là một event của thẻ <code>&lt;input&gt;</code> mà nó thực tế là một event property của <code>ngModel</code>. Khi Angular nhìn thấy cú pháp <code>[(abc)]</code> nó sẽ mong đợi directive <code>abc</code> có một input property <code>abc</code> và một ouput property <code>abc-change</code>.</p>
<p>Khi coi sơ qua code của <code>ngModel</code> ta sẽ thấy như sau (Code này có thể thay đổi khi Angular2 ra bản chính thức):</p>
<figure class="highlight less"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="variable">@Directive</span>(&#123;</div><div class="line">  <span class="attribute">selector</span>: <span class="string">'[ng-model]:not([ng-control]):not([ng-form-control])'</span>,</div><div class="line">  <span class="attribute">bindings</span>: [formControlBinding],</div><div class="line">  <span class="attribute">inputs</span>: [<span class="string">'model: ngModel'</span>],</div><div class="line">  <span class="attribute">outputs</span>: [<span class="string">'update: ngModelChange'</span>],</div><div class="line">  <span class="attribute">exportAs</span>: <span class="string">'form'</span></div><div class="line">&#125;)</div></pre></td></tr></table></figure>
<p><code>ng-model-change</code> là một <code>EventEmitter</code> của angular, nó sẽ trả về value cho input khi được gọi.</p>
<p>Nói chung là tìm hiểu một chút cho biết, còn bình thường thì ta cứ dùng <code>[(ng-model)]</code> cho khỏe.</p>
<h1 id="Validate-va-track-state-voi-ng-control"><a href="#Validate-va-track-state-voi-ng-control" class="headerlink" title="Validate và track state với ng-control"></a>Validate và track state với ng-control</h1><p>Ta sửa lại template phần form và add thêm style cho component như sau:</p>
<p>Form  </p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">form</span> (<span class="attr">ng-submit</span>)=<span class="string">"onSubmit()"</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">label</span>&gt;</span>Type<span class="tag">&lt;/<span class="name">lable</span>&gt;</span><span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">required</span> [(<span class="attr">ng-model</span>)]=<span class="string">"newAnimal.type"</span> <span class="attr">ng-control</span>=<span class="string">"type"</span> #<span class="attr">type</span>=<span class="string">"form"</span> <span class="attr">required</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">label</span>&gt;</span>Name<span class="tag">&lt;/<span class="name">lable</span>&gt;</span><span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">required</span> [(<span class="attr">ng-model</span>)]=<span class="string">"newAnimal.name"</span> <span class="attr">ng-control</span>=<span class="string">"name"</span> #<span class="attr">name</span>=<span class="string">"form"</span> <span class="attr">required</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">button</span> <span class="attr">type</span>=<span class="string">"submit"</span>&gt;</span>Add<span class="tag">&lt;/<span class="name">button</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"alert"</span> [<span class="attr">hidden</span>]=<span class="string">"type.valid"</span>&gt;</span>Type is required<span class="tag">&lt;/<span class="name">div</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"alert"</span> [<span class="attr">hidden</span>]=<span class="string">"name.valid"</span>&gt;</span>Name is required<span class="tag">&lt;/<span class="name">div</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">form</span>&gt;</span></div></pre></td></tr></table></figure>
<p>Styles  </p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="selector-tag">input</span> &#123; <span class="attribute">border</span>: <span class="number">1px</span> solid <span class="number">#ccc</span>; &#125;</div><div class="line"><span class="selector-class">.ng-invalid</span> &#123; <span class="attribute">border-left</span>: <span class="number">3px</span> solid red; &#125;</div><div class="line"><span class="selector-class">.alert</span> &#123; <span class="attribute">color</span>: red; &#125;</div></pre></td></tr></table></figure>
<p>Để có thể theo dõi được state của form controller ta sử dung directive <code>ng-control</code>, directive này chỉ có thể được áp dụng cho control bên trong thẻ <code>&lt;form&gt;</code>.</p>
<figure class="highlight stata"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">&lt;<span class="keyword">label</span>&gt;<span class="keyword">Type</span>&lt;/lable&gt;&lt;<span class="keyword">input</span> <span class="keyword">type</span>=<span class="string">"text"</span> required [(ng-model)]=<span class="string">"newAnimal.type"</span> ng-control=<span class="string">"type"</span> #<span class="keyword">type</span>=<span class="string">"form"</span> required&gt;</div></pre></td></tr></table></figure>
<p>Với mỗi <code>ng-control</code> ta cần gán cho nó một cái tên duy nhất. <code>ng-control</code> giúp ta biết được khi nào control được click (touch), khi nào giá trị thay đổi, khi nào thì giá trị bị sai. Và nó cũng thêm vào control một vài class đặc biệt của Angular.</p>
<table>
<thead>
<tr>
<th>State</th>
<th>Class if true</th>
<th>Class if false</th>
</tr>
</thead>
<tbody>
<tr>
<td>Control has been visited</td>
<td>ng-touched</td>
<td>ng-untouched</td>
</tr>
<tr>
<td>Control’s value has changed</td>
<td>ng-dirty</td>
<td>ng-pristine</td>
</tr>
<tr>
<td>Control’s value is valid</td>
<td>ng-valid</td>
<td>ng-invalid</td>
</tr>
</tbody>
</table>
<p>Vì input của ta có thuộc tính <code>required</code> nên khi không có giá trị nào bên trong, <code>ng-control</code> sẽ tự động thêm vào class <code>ng-invalid</code> do đó ta sẽ thấy input của mình như thế này:</p>
<p><a href="http://localhost:8000/images/angular2-input-invalid.png" title="input invalid" target="_blank" rel="external"><img src="/images/angular2-input-invalid.png" alt="input invalid"></a><span class="caption">input invalid</span></p>
<h2 id="Hien-thi-thong-bao-loi-khi-input-khong-dung"><a href="#Hien-thi-thong-bao-loi-khi-input-khong-dung" class="headerlink" title="Hiển thị thông báo lỗi khi input không đúng"></a>Hiển thị thông báo lỗi khi input không đúng</h2><p>Trong input ta tạo một local variable <code>#type=&quot;form&quot;</code> và gán cho nó từ <code>form</code>. Angular tự hiểu cú pháp này và gán <code>Control</code> Object cho biến <code>type</code>. Do đó ta có thể bind giá trị <code>type.valid</code> vào property <code>hidden</code> của thẻ <code>div</code>:</p>
<figure class="highlight applescript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">&lt;<span class="keyword">div</span> <span class="built_in">class</span>=<span class="string">"alert"</span> [hidden]=<span class="string">"type.valid"</span>&gt;Type <span class="keyword">is</span> required&lt;/<span class="keyword">div</span>&gt;</div></pre></td></tr></table></figure>
<p><a href="http://localhost:8000/images/angular2-error-message.png" title="error message" target="_blank" rel="external"><img src="/images/angular2-error-message.png" alt="error message"></a><span class="caption">error message</span></p>
<h2 id="Ngan-form-submit-khi-du-lieu-invalid"><a href="#Ngan-form-submit-khi-du-lieu-invalid" class="headerlink" title="Ngăn form submit khi dữ liệu invalid"></a>Ngăn form submit khi dữ liệu invalid</h2><p>Ta tạo một local variable <code>animalForm</code> và disable nút <code>Add</code> khi dữ liệu trong form invalid.</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">form</span> (<span class="attr">ng-submit</span>)=<span class="string">"onSubmit()"</span> #<span class="attr">animalform</span>=<span class="string">"form"</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">label</span>&gt;</span>Type<span class="tag">&lt;/<span class="name">lable</span>&gt;</span><span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">required</span> [(<span class="attr">ng-model</span>)]=<span class="string">"newAnimal.type"</span> <span class="attr">ng-control</span>=<span class="string">"type"</span> #<span class="attr">type</span>=<span class="string">"form"</span> <span class="attr">required</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">label</span>&gt;</span>Name<span class="tag">&lt;/<span class="name">lable</span>&gt;</span><span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">required</span> [(<span class="attr">ng-model</span>)]=<span class="string">"newAnimal.name"</span> <span class="attr">ng-control</span>=<span class="string">"name"</span> #<span class="attr">name</span>=<span class="string">"form"</span> <span class="attr">required</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">button</span> <span class="attr">type</span>=<span class="string">"submit"</span> [<span class="attr">disabled</span>]=<span class="string">"!animalform.form.valid"</span>&gt;</span>Add<span class="tag">&lt;/<span class="name">button</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"alert"</span> [<span class="attr">hidden</span>]=<span class="string">"type.valid"</span>&gt;</span>Type is required<span class="tag">&lt;/<span class="name">div</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"alert"</span> [<span class="attr">hidden</span>]=<span class="string">"name.valid"</span>&gt;</span>Name is required<span class="tag">&lt;/<span class="name">div</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">form</span>&gt;</span></div></pre></td></tr></table></figure>
<p>Khi mới chạy ta sẽ thấy nút <code>Add</code> bị disabled, sau khi đã điền đủ thông tin vào name và type, nút <code>Add</code> sẽ được enable trở lại và ta có thể submit form.</p>
<h1 id="Tong-ket"><a href="#Tong-ket" class="headerlink" title="Tổng kết"></a>Tổng kết</h1><p><a href="http://localhost:8000/images/angular2-zoo-app-2.png" title="zoo app version 2" target="_blank" rel="external"><img src="/images/angular2-zoo-app-2.png" alt="zoo app version 2"></a><span class="caption">zoo app version 2</span></p>
<p>Sau phần này, ta đã biết cách sử dụng <code>ng-model</code> cho two-way data binding. Tìm hiểu một chút về cách <code>[(ng-model)]</code> hoạt động.<br>Sử dụng <code>ng-control</code> để theo dõi trạng thái của <code>control</code>, cũng như thêm style cho control, ẩn hiện thông báo lỗi tùy vào trạng thái của control.</p>
<p>Toàn bộ code của phần 2.</p>
<p><code>app.ts</code></p>
<figure class="highlight scala"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> &#123;<span class="type">Component</span>, bootstrap, <span class="type">CORE_DIRECTIVES</span>, <span class="type">FORM_DIRECTIVES</span>&#125; from <span class="symbol">'angular2</span>/angular2';</div><div class="line"></div><div class="line"><span class="meta">@Component</span>(&#123;</div><div class="line">  selector: <span class="symbol">'ap</span>p',</div><div class="line">  directives: [<span class="type">CORE_DIRECTIVES</span>, <span class="type">FORM_DIRECTIVES</span>],</div><div class="line">  template: `</div><div class="line">    &lt;h1&gt;<span class="type">Animal</span> list&lt;/h1&gt;</div><div class="line">    &lt;form (ng-submit)=<span class="string">"onSubmit()"</span> #animalform=<span class="string">"form"</span>&gt;</div><div class="line">      &lt;label&gt;<span class="type">Type</span>&lt;/lable&gt;&lt;input <span class="class"><span class="keyword">type</span></span>=<span class="string">"text"</span> required [(ng-model)]=<span class="string">"newAnimal.type"</span> ng-control=<span class="string">"type"</span> #<span class="class"><span class="keyword">type</span></span>=<span class="string">"form"</span> required&gt;</div><div class="line">      &lt;label&gt;<span class="type">Name</span>&lt;/lable&gt;&lt;input <span class="class"><span class="keyword">type</span></span>=<span class="string">"text"</span> required [(ng-model)]=<span class="string">"newAnimal.name"</span> ng-control=<span class="string">"name"</span> #name=<span class="string">"form"</span> required&gt;</div><div class="line">      &lt;button <span class="class"><span class="keyword">type</span></span>=<span class="string">"submit"</span> [disabled]=<span class="string">"!animalform.form.valid"</span>&gt;<span class="type">Add</span>&lt;/button&gt;</div><div class="line">      &lt;div <span class="class"><span class="keyword">class</span></span>=<span class="string">"alert"</span> [hidden]=<span class="string">"type.valid"</span>&gt;<span class="type">Type</span> is required&lt;/div&gt;</div><div class="line">      &lt;div <span class="class"><span class="keyword">class</span></span>=<span class="string">"alert"</span> [hidden]=<span class="string">"name.valid"</span>&gt;<span class="type">Name</span> is required&lt;/div&gt;</div><div class="line">    &lt;/form&gt;</div><div class="line">    &lt;ul <span class="class"><span class="keyword">class</span></span>=<span class="string">"animal-list"</span>&gt;</div><div class="line">      &lt;li *ng-<span class="keyword">for</span>=<span class="string">"#animal of animals"</span> (click)=<span class="string">"select(animal)"</span> [ng-<span class="class"><span class="keyword">class</span>]</span>=<span class="string">"getSelectedClass(animal)"</span>&gt;</div><div class="line">        &lt;span <span class="class"><span class="keyword">class</span></span>=<span class="string">"type"</span>&gt;&#123;&#123;animal.<span class="keyword">type</span>&#125;&#125;&lt;/span&gt; &#123;&#123;animal.name&#125;&#125;</div><div class="line">      &lt;/li&gt;</div><div class="line">    &lt;/ul&gt;</div><div class="line">    &lt;div *ng-<span class="keyword">if</span>=<span class="string">"selectedAnimal"</span>&gt;</div><div class="line">      &lt;h2&gt;<span class="type">Selected</span> <span class="type">Animal</span>&lt;/h2&gt;</div><div class="line">      (&#123;&#123;selectedAnimal.<span class="keyword">type</span>&#125;&#125;) &#123;&#123;selectedAnimal.name&#125;&#125;</div><div class="line">    &lt;/div&gt;</div><div class="line">  `,</div><div class="line">  styles: [`</div><div class="line">    .animal-list &#123; list-style-<span class="class"><span class="keyword">type</span></span>: none; padding: <span class="number">0</span>; &#125;</div><div class="line">    .animal-list li &#123; cursor: pointer; &#125;</div><div class="line">    .animal-list li:hover &#123; cursor: pointer; font-weight: bold; &#125;</div><div class="line">    .animal-list li .<span class="keyword">type</span> &#123; background: #<span class="type">FF9800</span>; color: #<span class="type">FFF</span>; padding: <span class="number">2</span>px <span class="number">4</span>px; line-height: <span class="number">1.5</span>em;&#125;</div><div class="line">    .selected &#123; font-weight: bold; &#125;</div><div class="line">    input &#123; border: <span class="number">1</span>px solid #ccc; &#125;</div><div class="line">    .ng-invalid &#123; border-left: <span class="number">3</span>px solid red; &#125;</div><div class="line">    .alert &#123; color: red; &#125;</div><div class="line">  `]</div><div class="line">&#125;)</div><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">AppComponent</span> </span>&#123;</div><div class="line">  public selectedAnimal;</div><div class="line">  public newAnimal = &#123;</div><div class="line">    <span class="class"><span class="keyword">type</span></span>: '',</div><div class="line">    name: ''</div><div class="line">  &#125;</div><div class="line"></div><div class="line">  animals = [</div><div class="line">    &#123; <span class="class"><span class="keyword">type</span></span>: <span class="symbol">'Tige</span>r', name: <span class="symbol">'Bob</span>o'&#125;,</div><div class="line">    &#123; <span class="class"><span class="keyword">type</span></span>: <span class="symbol">'Do</span>g', name: <span class="symbol">'Mi</span>c'&#125;,</div><div class="line">    &#123; <span class="class"><span class="keyword">type</span></span>: <span class="symbol">'Elepha</span>n', name: <span class="symbol">'Bi</span>g'&#125;</div><div class="line">  ];</div><div class="line"></div><div class="line">  select(animal) &#123; <span class="keyword">this</span>.selectedAnimal = animal; &#125;</div><div class="line"></div><div class="line">  getSelectedClass(animal) &#123;</div><div class="line">    <span class="keyword">return</span> &#123;</div><div class="line">      <span class="symbol">'selecte</span>d': animal === <span class="keyword">this</span>.selectedAnimal</div><div class="line">    &#125;</div><div class="line">  &#125;</div><div class="line"></div><div class="line">  onSubmit() &#123;</div><div class="line">    <span class="keyword">this</span>.animals.push(&#123;</div><div class="line">      <span class="class"><span class="keyword">type</span></span>: <span class="keyword">this</span>.newAnimal.<span class="keyword">type</span>,</div><div class="line">      name: <span class="keyword">this</span>.newAnimal.name</div><div class="line">    &#125;);</div><div class="line"></div><div class="line">    <span class="keyword">this</span>.newAnimal.<span class="keyword">type</span> = '';</div><div class="line">    <span class="keyword">this</span>.newAnimal.name = '';</div><div class="line">  &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line">bootstrap(<span class="type">AppComponent</span>);</div></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Ở &lt;a href=&quot;/2015/12/04/lam-quen-voi-angular2-zoo-app-part-1/&quot;&gt;phần 1&lt;/a&gt; chúng ta đã sử dụng một vài directives cơ bản của Angular như NgFor, NgIf, NgClass và ta cũng biết rằng muốn sử dụng directive nào, ta phải khai báo directive đó cho Component. Tuy nhiên việc phải khai báo từng directive như vậy thật bất tiện. Để khắc phục điều đó, Angular 2 đã gộp các core directives vào một tập hợp là &lt;code&gt;CORE_DIRECTIVES&lt;/code&gt; ta chỉ cần khai báo nó một lần là có thể dùng được các core directives của Angular. Trước khi vào phần 2 ta thay đổi một chút như sau:&lt;/p&gt;
&lt;figure class=&quot;highlight gradle&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;1&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;2&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;3&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;4&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &amp;#123;Component, bootstrap, CORE_DIRECTIVES, FORM_DIRECTIVES&amp;#125; &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&#39;angular2/angular2&#39;&lt;/span&gt;;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;...&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;  directives: [CORE_DIRECTIVES, FORM_DIRECTIVES],&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;Ngoài &lt;code&gt;CORE_DIRECTIVES&lt;/code&gt; ra mình còn khai báo thêm &lt;code&gt;FORM_DIRECTIVES&lt;/code&gt;, chắc hẳn là bạn đã đoán ra đó là tập hợp các directive dành cho Form của Angular.&lt;/p&gt;
    
    </summary>
    
    
      <category term="Angular2" scheme="http://saysua.com/tags/Angular2/"/>
    
  </entry>
  
  <entry>
    <title>Làm quen với Angular 2 - Zoo app - part 1</title>
    <link href="http://saysua.com/2015/12/04/lam-quen-voi-angular2-zoo-app-part-1/"/>
    <id>http://saysua.com/2015/12/04/lam-quen-voi-angular2-zoo-app-part-1/</id>
    <published>2015-12-04T04:05:24.000Z</published>
    <updated>2016-10-16T08:51:22.875Z</updated>
    
    <content type="html"><![CDATA[<p>Trước khi bắt đầu, bạn nên coi qua bài <a href="/2015/12/02/lam-quen-voi-Angular2-Tao-mot-ung-dung-don-gian-bang-TypeScript/">Làm quen với Angular 2 - Tạo một ứng dụng bằng TypeScript</a> để có khái niệm cơ bản về Angular2 và làm việc với Typescript.</p>
<p>Ở bài này, mình sẽ viết một ứng dụng quản lý sở thú bằng Angular 2 với typescript. Sau khi kết thúc ta sẽ có một ứng dụng như sau:</p>
<p><a href="http://localhost:8000/images/angular2-animal-selected-animal.png" title="zoo app" target="_blank" rel="external"><img src="/images/angular2-animal-selected-animal.png" alt="zoo app"></a></p>
<a id="more"></a>
<p>Tạo một thư mục để chứa ứng dụng.</p>
<figure class="highlight dos"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">mkdir</span> angular-zoo</div><div class="line"><span class="built_in">cd</span> angular-zoo</div></pre></td></tr></table></figure>
<p>Ở đây, mình sẽ dùng <code>live-server</code> để chạy một static server, nó sẽ giúp trang web tự động tải lại khi nội dung file được thay đổi.</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm <span class="keyword">install</span> -g live-<span class="keyword">server</span></div></pre></td></tr></table></figure>
<h1 id="App-Component"><a href="#App-Component" class="headerlink" title="App Component"></a>App Component</h1><p>Trong thư mục ứng dụng, tạo file <code>app.ts</code> với nội dung sau:</p>
<figure class="highlight scala"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> &#123;<span class="type">Component</span>, bootstrap&#125; from <span class="symbol">'angular2</span>/angular2';</div><div class="line"></div><div class="line"><span class="meta">@Component</span>(&#123;</div><div class="line">  selector: <span class="symbol">'ap</span>p',</div><div class="line">  template: `</div><div class="line">    &lt;h1&gt;<span class="type">Animal</span> list&lt;/h1&gt;</div><div class="line">    &lt;ul <span class="class"><span class="keyword">class</span></span>=<span class="string">"animal-list"</span>&gt;</div><div class="line">      &lt;li *ng-<span class="keyword">for</span>=<span class="string">"#animal of animals"</span>&gt;</div><div class="line">        &lt;span <span class="class"><span class="keyword">class</span></span>=<span class="string">"type"</span>&gt;&#123;&#123;animal.<span class="keyword">type</span>&#125;&#125;&lt;/span&gt; &#123;&#123;animal.name&#125;&#125;</div><div class="line">      &lt;/li&gt;</div><div class="line">    &lt;/ul&gt;</div><div class="line">  `</div><div class="line">&#125;)</div><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">AppComponent</span> </span>&#123;</div><div class="line">  animals = [</div><div class="line">    &#123; <span class="class"><span class="keyword">type</span></span>: <span class="symbol">'Tige</span>r', name: <span class="symbol">'Bob</span>o'&#125;,</div><div class="line">    &#123; <span class="class"><span class="keyword">type</span></span>: <span class="symbol">'Do</span>g', name: <span class="symbol">'Mi</span>c'&#125;,</div><div class="line">    &#123; <span class="class"><span class="keyword">type</span></span>: <span class="symbol">'Elepha</span>n', name: <span class="symbol">'Bi</span>g'&#125;</div><div class="line">  ];</div><div class="line">&#125;</div><div class="line"></div><div class="line">bootstrap(<span class="type">AppComponent</span>);</div></pre></td></tr></table></figure>
<p>Ở đây, ta có directive <code>ng-for</code> là một repeater directive của Angular 2.</p>
<p><strong>Chú ý</strong>: Dấu * trước <code>ng-for</code> là cần thiết. Nó cho <code>ng-for</code> biết rằng, thẻ <code>&lt;li&gt;</code> và nội dung trong nó chính là template của từng phần tử.</p>
<p>Bằng cách sử dụng typescript, ta có một cách để viết chuỗi với nhiều dòng như phần <code>template</code> của <code>Component</code>, đó là sử dụng dấu ` (Không phải là dấu nháy đơn, dấu này trên bàn phím thường nằm ở phím dưới phím ESC)</p>
<h1 id="index-html"><a href="#index-html" class="headerlink" title="index.html"></a>index.html</h1><p>Tiếp tục, tạo file <code>index.html</code> với nội dung sau:</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">head</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>Angular 2 QuickStart<span class="tag">&lt;/<span class="name">title</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://code.angularjs.org/tools/system.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://code.angularjs.org/tools/typescript.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://code.angularjs.org/2.0.0-alpha.44/angular2.dev.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="actionscript"></span></div><div class="line">      System.config(&#123;</div><div class="line">        transpiler: <span class="string">'typescript'</span>,</div><div class="line">        typescriptOptions: &#123; emitDecoratorMetadata: <span class="literal">true</span> &#125;</div><div class="line">      &#125;);</div><div class="line">      System.import(<span class="string">'./app.ts'</span>);</div><div class="line">    <span class="tag">&lt;/<span class="name">script</span>&gt;</span></div><div class="line">  <span class="tag">&lt;/<span class="name">head</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">body</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">app</span>&gt;</span>loading...<span class="tag">&lt;/<span class="name">app</span>&gt;</span></div><div class="line">  <span class="tag">&lt;/<span class="name">body</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></div></pre></td></tr></table></figure>
<h1 id="Chay-server"><a href="#Chay-server" class="headerlink" title="Chạy server"></a>Chạy server</h1><p>Mở terminal và chạy lệnh</p>
<figure class="highlight axapta"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">live-<span class="keyword">server</span></div></pre></td></tr></table></figure>
<p>Nếu như mọi chuyện đều ổn, ta sẽ nhìn thấy một danh sách các con vật với loại và tên, tuy nhiên, ta chỉ thấy dòng chữ <code>loading...</code>. Bật develop tool của trình duyệt lên (ở đây mình dùng Chrome) ta sẽ thấy lỗi:</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">EXCEPTION: Template parse errors:</div><div class="line">Can<span class="string">'t bind to '</span>ngForOf<span class="string">' since it isn'</span>t <span class="selector-tag">a</span> known native property <span class="keyword">in</span> AppComponent &gt; <span class="selector-tag">ul</span>:nth-child(<span class="number">1</span>) &gt; <span class="selector-tag">li</span>:nth-child(<span class="number">1</span>)[*ng-<span class="keyword">for</span>=<span class="selector-id">#animal</span> of animals]</div></pre></td></tr></table></figure>
<p>Lý do là do ta dùng directive <code>ng-for</code> trong template, nhưng ứng dụng không biết directive đó ở đâu. Ta sẽ sửa nó bằng cách import <code>ng-for</code> vào và nhúng vào app component.</p>
<p>Trong file <code>app.ts</code> ta sửa lại dòng import:</p>
<figure class="highlight gradle"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> &#123;Component, bootstrap, NgFor&#125; <span class="keyword">from</span> <span class="string">'angular2/angular2'</span>;</div></pre></td></tr></table></figure>
<p>và trong component ngay dưới thuộc tính <code>selector</code> ta thêm vào thuộc tính <code>directives</code> để cho component của ta biết template sẽ sử dụng những directives nào.</p>
<figure class="highlight django"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="xml">@Component(&#123;</span></div><div class="line">  selector: 'app',</div><div class="line">  directives: [NgFor],</div><div class="line">  template: `</div><div class="line">    <span class="tag">&lt;<span class="name">h1</span>&gt;</span>Animal list<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">ul</span> <span class="attr">class</span>=<span class="string">"animal-list"</span>&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">li</span> *<span class="attr">ng-for</span>=<span class="string">"#animal of animals"</span>&gt;</span></div><div class="line">        <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">"type"</span>&gt;</span><span class="template-variable">&#123;&#123;animal.type&#125;&#125;</span><span class="xml"><span class="tag">&lt;/<span class="name">span</span>&gt;</span> </span><span class="template-variable">&#123;&#123;animal.name&#125;&#125;</span><span class="xml"></span></div><div class="line">      <span class="tag">&lt;/<span class="name">li</span>&gt;</span></div><div class="line">    <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></div><div class="line">  `</div><div class="line">&#125;)</div></pre></td></tr></table></figure>
<p><strong>Ghi chú:</strong> Dấu # trước <code>animal</code> nghĩa là Angular sẽ tạo 1 local variable có tên là <code>animal</code></p>
<p><a href="http://localhost:8000/images/angular2-animal-list.png" title="animal list" target="_blank" rel="external"><img src="/images/angular2-animal-list.png" alt="animal list"></a></p>
<h1 id="Them-style-cho-app-component"><a href="#Them-style-cho-app-component" class="headerlink" title="Thêm style cho app component"></a>Thêm style cho app component</h1><p>Để thêm style cho app component, trong decorator component ta thêm vào thuộc tính <code>styles</code>, style này chỉ được áp dụng bên trong app component.</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">styles: [`</div><div class="line">  <span class="selector-class">.animal-list</span> &#123; <span class="attribute">list-style-type</span>: none; <span class="attribute">padding</span>: <span class="number">0</span>; &#125;</div><div class="line">  <span class="selector-class">.animal-list</span> <span class="selector-tag">li</span> &#123; <span class="attribute">cursor</span>: pointer; &#125;</div><div class="line">  <span class="selector-class">.animal-list</span> <span class="selector-tag">li</span>:hover &#123; <span class="attribute">cursor</span>: pointer; <span class="attribute">font-weight</span>: bold; &#125;</div><div class="line">  <span class="selector-class">.animal-list</span> <span class="selector-tag">li</span> <span class="selector-class">.type</span> &#123; <span class="attribute">background</span>: <span class="number">#FF9800</span>; <span class="attribute">color</span>: <span class="number">#FFF</span>; <span class="attribute">padding</span>: <span class="number">2px</span> <span class="number">4px</span>; <span class="attribute">line-height</span>: <span class="number">1.5em</span>;&#125;</div><div class="line">`]</div></pre></td></tr></table></figure>
<p><a href="http://localhost:8000/images/angular2-animal-list-with-style.png" title="animal list with style" target="_blank" rel="external"><img src="/images/angular2-animal-list-with-style.png" alt="animal list with style"></a><span class="caption">animal list with style</span></p>
<h1 id="Them-su-kien-click"><a href="#Them-su-kien-click" class="headerlink" title="Thêm sự kiện click"></a>Thêm sự kiện click</h1><p>Giờ ta sẽ thêm vào một chức năng, khi click vào một con vật thì sẽ hiển thị thông tin của con vật được chọn.</p>
<p>Trước tiên sửa lại template:</p>
<figure class="highlight django"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="xml"><span class="tag">&lt;<span class="name">h1</span>&gt;</span>Animal list<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span></div><div class="line"><span class="tag">&lt;<span class="name">ul</span> <span class="attr">class</span>=<span class="string">"animal-list"</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">li</span> *<span class="attr">ng-for</span>=<span class="string">"#animal of animals"</span> (<span class="attr">click</span>)=<span class="string">"select(animal)"</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">"type"</span>&gt;</span><span class="template-variable">&#123;&#123;animal.type&#125;&#125;</span><span class="xml"><span class="tag">&lt;/<span class="name">span</span>&gt;</span> </span><span class="template-variable">&#123;&#123;animal.name&#125;&#125;</span><span class="xml"></span></div><div class="line">  <span class="tag">&lt;/<span class="name">li</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">ul</span>&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">div</span> *<span class="attr">ng-if</span>=<span class="string">"selectedAnimal"</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">h2</span>&gt;</span>Selected Animal<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></div><div class="line">  (<span class="template-variable">&#123;&#123;selectedAnimal.type&#125;&#125;</span><span class="xml">) </span><span class="template-variable">&#123;&#123;selectedAnimal.name&#125;&#125;</span><span class="xml"></span></div><div class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></div></pre></td></tr></table></figure>
<p>Ở đây ta sẽ sử dụng thêm <code>ng-if</code> (chỉ hiển thị khi điều kiện của ng-if cho giá trị đúng), cũng giống như <code>ng-for</code> ở trên ta phải import <code>NgIf</code> vào và add thêm và phần <code>directives</code> của component.</p>
<p>Trong thẻ <code>&lt;li&gt;</code> ta đã thêm vào <code>(click)=&quot;select(animal)&quot;</code>, nghĩa là khi click vào thẻ <code>li</code> ta Angular sẽ gọi phương thức <code>select</code> của component cùng với tham số là <code>animal</code>. So với AngularJS 1, ta không còn <code>ng-click</code> nữa. Ở đây <code>(click)</code>, dấu ngoặc sẽ xác định mục tiêu là sự kiện click của thẻ <code>li</code>, như vậy ta có thể tạm đoán dấu () sẽ giúp ta có thể làm việc được với bất kỳ sự kiện nào của element.</p>
<p>Tiếp đến, ta cần thêm phương thức <code>select</code> vào component và một thuộc tính <code>selectedAnimal</code>:</p>
<figure class="highlight armasm"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="symbol">public</span> <span class="keyword">selectedAnimal;</span></div><div class="line"></div><div class="line"><span class="keyword">select(animal) </span>&#123; this.<span class="keyword">selectedAnimal </span>= animal<span class="comment">; &#125;</span></div></pre></td></tr></table></figure>
<h1 id="Thay-doi-style-cho-con-vat-duoc-chon-voi-ng-class"><a href="#Thay-doi-style-cho-con-vat-duoc-chon-voi-ng-class" class="headerlink" title="Thay đổi style cho con vật được chọn với ng-class"></a>Thay đổi style cho con vật được chọn với ng-class</h1><p>Ta sửa lại thẻ <code>li</code>, thêm vào directive <code>ng-class</code></p>
<figure class="highlight django"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="xml"><span class="tag">&lt;<span class="name">li</span> *<span class="attr">ng-for</span>=<span class="string">"#animal of animals"</span> (<span class="attr">click</span>)=<span class="string">"select(animal)"</span> [<span class="attr">ng-class</span>]=<span class="string">"getSelectedClass(animal)"</span>&gt;</span></span></div><div class="line">  <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">"type"</span>&gt;</span><span class="template-variable">&#123;&#123;animal.type&#125;&#125;</span><span class="xml"><span class="tag">&lt;/<span class="name">span</span>&gt;</span> </span><span class="template-variable">&#123;&#123;animal.name&#125;&#125;</span><span class="xml"></span></div><div class="line"><span class="tag">&lt;/<span class="name">li</span>&gt;</span></div></pre></td></tr></table></figure>
<p>sau đó trong component ta thêm phương thức <code>getSelectedClass</code>:</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">getSelectedClass(animal) &#123;</div><div class="line">  <span class="keyword">return</span> &#123;</div><div class="line">    <span class="string">'selected'</span>: animal === <span class="keyword">this</span>.selectedAnimal</div><div class="line">  &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>phương thức này trả về đối tượng với thuộc tính <code>selected</code> bằng <code>true</code> nếu <code>animal</code> trùng với <code>selectedAnimal</code>.</p>
<p><strong>Ghi chú:</strong> <code>ng-class</code> được bọc trong dấu [] đây là cú pháp của <code>property binding</code> mà dữ liệu sẽ đi theo 1 chiều từ nguồn là <code>getSelectedClass(animal)</code> đến đích là property của directive <code>ng-class</code>.</p>
<p>để thấy được sự thay đổi của <code>li</code> sau khi được chọn ta thêm style cho class <code>.selected</code>:</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="selector-class">.selected</span> &#123; <span class="attribute">font-weight</span>: bold; &#125;</div></pre></td></tr></table></figure>
<p><a href="http://localhost:8000/images/angular2-animal-selected-animal.png" title="selected animal" target="_blank" rel="external"><img src="/images/angular2-animal-selected-animal.png" alt="selected animal"></a></p>
<h1 id="Tong-ket"><a href="#Tong-ket" class="headerlink" title="Tổng kết"></a>Tổng kết</h1><p>Như vậy là trong phần này ta đã cùng nhau tìm hiểu về một vài directive có sẵn của Angular 2 như <code>ng-for</code> , <code>ng-if</code>, <code>ng-class</code>, cách khai báo directive sử dụng trong component.</p>
<p>Để bind event của element ta sử dụng cặp dấu ngoặc <code>()</code>, để bind property ta dùng cặp dấu ngoặc <code>[]</code>.</p>
<p>Ở phần tiếp theo, ta sẽ cùng dùng thử form trong Angular 2 để add thêm con vật vào sở thú của mình.</p>
<p>Đây là toàn bộ code của phiên bản zoo app hiện tại:</p>
<figure class="highlight scala"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> &#123;<span class="type">Component</span>, bootstrap, <span class="type">NgFor</span>, <span class="type">NgIf</span>, <span class="type">NgClass</span>&#125; from <span class="symbol">'angular2</span>/angular2';</div><div class="line"></div><div class="line"><span class="meta">@Component</span>(&#123;</div><div class="line">  selector: <span class="symbol">'ap</span>p',</div><div class="line">  directives: [<span class="type">NgFor</span>, <span class="type">NgIf</span>, <span class="type">NgClass</span>],</div><div class="line">  template: `</div><div class="line">    &lt;h1&gt;<span class="type">Animal</span> list&lt;/h1&gt;</div><div class="line">    &lt;ul <span class="class"><span class="keyword">class</span></span>=<span class="string">"animal-list"</span>&gt;</div><div class="line">      &lt;li *ng-<span class="keyword">for</span>=<span class="string">"#animal of animals"</span> (click)=<span class="string">"select(animal)"</span> [ng-<span class="class"><span class="keyword">class</span>]</span>=<span class="string">"getSelectedClass(animal)"</span>&gt;</div><div class="line">        &lt;span <span class="class"><span class="keyword">class</span></span>=<span class="string">"type"</span>&gt;&#123;&#123;animal.<span class="keyword">type</span>&#125;&#125;&lt;/span&gt; &#123;&#123;animal.name&#125;&#125;</div><div class="line">      &lt;/li&gt;</div><div class="line">    &lt;/ul&gt;</div><div class="line">    &lt;div *ng-<span class="keyword">if</span>=<span class="string">"selectedAnimal"</span>&gt;</div><div class="line">      &lt;h2&gt;<span class="type">Selected</span> <span class="type">Animal</span>&lt;/h2&gt;</div><div class="line">      (&#123;&#123;selectedAnimal.<span class="keyword">type</span>&#125;&#125;) &#123;&#123;selectedAnimal.name&#125;&#125;</div><div class="line">    &lt;/div&gt;</div><div class="line">  `,</div><div class="line">  styles: [`</div><div class="line">    .animal-list &#123; list-style-<span class="class"><span class="keyword">type</span></span>: none; padding: <span class="number">0</span>; &#125;</div><div class="line">    .animal-list li &#123; cursor: pointer; &#125;</div><div class="line">    .animal-list li:hover &#123; cursor: pointer; font-weight: bold; &#125;</div><div class="line">    .animal-list li .<span class="keyword">type</span> &#123; background: #<span class="type">FF9800</span>; color: #<span class="type">FFF</span>; padding: <span class="number">2</span>px <span class="number">4</span>px; line-height: <span class="number">1.5</span>em;&#125;</div><div class="line">    .selected &#123; font-weight: bold; &#125;</div><div class="line">  `]</div><div class="line">&#125;)</div><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">AppComponent</span> </span>&#123;</div><div class="line">  public selectedAnimal;</div><div class="line"></div><div class="line">  animals = [</div><div class="line">    &#123; <span class="class"><span class="keyword">type</span></span>: <span class="symbol">'Tige</span>r', name: <span class="symbol">'Bob</span>o'&#125;,</div><div class="line">    &#123; <span class="class"><span class="keyword">type</span></span>: <span class="symbol">'Do</span>g', name: <span class="symbol">'Mi</span>c'&#125;,</div><div class="line">    &#123; <span class="class"><span class="keyword">type</span></span>: <span class="symbol">'Elepha</span>n', name: <span class="symbol">'Bi</span>g'&#125;</div><div class="line">  ];</div><div class="line"></div><div class="line">  select(animal) &#123; <span class="keyword">this</span>.selectedAnimal = animal; &#125;</div><div class="line"></div><div class="line">  getSelectedClass(animal) &#123;</div><div class="line">    <span class="keyword">return</span> &#123;</div><div class="line">      <span class="symbol">'selecte</span>d': animal === <span class="keyword">this</span>.selectedAnimal</div><div class="line">    &#125;</div><div class="line">  &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line">bootstrap(<span class="type">AppComponent</span>);</div></pre></td></tr></table></figure>
<p>Tiếp theo: <a href="/2015/12/10/lam-quen-voi-angular2-zoo-app-part-2/">zoo app phần 2</a>.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Trước khi bắt đầu, bạn nên coi qua bài &lt;a href=&quot;/2015/12/02/lam-quen-voi-Angular2-Tao-mot-ung-dung-don-gian-bang-TypeScript/&quot;&gt;Làm quen với Angular 2 - Tạo một ứng dụng bằng TypeScript&lt;/a&gt; để có khái niệm cơ bản về Angular2 và làm việc với Typescript.&lt;/p&gt;
&lt;p&gt;Ở bài này, mình sẽ viết một ứng dụng quản lý sở thú bằng Angular 2 với typescript. Sau khi kết thúc ta sẽ có một ứng dụng như sau:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://localhost:8000/images/angular2-animal-selected-animal.png&quot; title=&quot;zoo app&quot;&gt;&lt;img src=&quot;/images/angular2-animal-selected-animal.png&quot; alt=&quot;zoo app&quot;&gt;&lt;/a&gt;&lt;/p&gt;
    
    </summary>
    
    
      <category term="Angular2" scheme="http://saysua.com/tags/Angular2/"/>
    
  </entry>
  
  <entry>
    <title>Làm quen với Angular 2 - Tạo một ứng dụng bằng TypeScript</title>
    <link href="http://saysua.com/2015/12/02/lam-quen-voi-Angular2-Tao-mot-ung-dung-don-gian-bang-TypeScript/"/>
    <id>http://saysua.com/2015/12/02/lam-quen-voi-Angular2-Tao-mot-ung-dung-don-gian-bang-TypeScript/</id>
    <published>2015-12-02T07:48:27.000Z</published>
    <updated>2016-10-16T01:41:54.106Z</updated>
    
    <content type="html"><![CDATA[<p>Angular2 hiện tại vẫn đang trong giai đoạn <code>Developer Preview</code> tuy nhiên mình sẽ bắt đầu tìm hiểu trước cho đến khi nó được <code>release</code> thì dùng luôn. Hiện tại trên trang của Angular2 thấy chúng ta có thể code bằng <code>Javascript</code>, <code>Typescript</code> và <code>Dart</code>, nhưng xem qua các bài hướng dẫn thì mọi người có vẻ dùng <code>Typescript</code> phổ biến hơn. Nên mình cũng sẽ làm quen với Angular2 bằng Typescript luôn.</p>
<p>Trong phần làm quen này, chúng ta cùng nhau viết ứng dụng vô cùng đơn giản coi như để biết được Angular2 là cái gì, và viết nó như thế nào. Một ứng dụng Hello World.</p>
<a id="more"></a>
<p>Chúng ta sẽ cùng nhau thực hiện các bước sau:</p>
<ul>
<li>Tạo thư mục</li>
<li>Tạo Component gốc trong file <code>app.ts</code></li>
<li>Nhúng các thư viện và code vào file <code>index.html</code></li>
<li>Chạy ứng dụng</li>
<li>Cải tiến một vài phần cho ứng dụng</li>
</ul>
<h1 id="Tao-thu-muc"><a href="#Tao-thu-muc" class="headerlink" title="Tạo thư mục"></a>Tạo thư mục</h1><figure class="highlight dos"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">mkdir</span> angular2</div><div class="line"><span class="built_in">cd</span> angular2</div></pre></td></tr></table></figure>
<h1 id="Tao-Component-goc-trong-file-app-ts"><a href="#Tao-Component-goc-trong-file-app-ts" class="headerlink" title="Tạo Component gốc trong file app.ts"></a>Tạo Component gốc trong file app.ts</h1><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> &#123;bootstrap, Component&#125; from <span class="string">'angular2/angular2'</span>;</div><div class="line"></div><div class="line"><span class="meta">@Component(&#123;</span></div><div class="line">  selector: <span class="meta-string">'my-app'</span>,</div><div class="line">  template: <span class="meta-string">'&lt;h1&gt;Hello Angular2&lt;/h1&gt;'</span></div><div class="line">&#125;)</div><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">AppComponent</span> </span>&#123; &#125;</div><div class="line"></div><div class="line">bootstrap(AppComponent);</div></pre></td></tr></table></figure>
<p>Ở trên, mình đã tạo ra một <code>Component</code>, thành phần quan trọng nhất trong Angular 2. Ta có thể coi nó như phần <code>views</code> của ứng dụng. Hiện tại <code>AppComponent</code> của chúng ta là một class rỗng, chưa làm gì cả.</p>
<p>Trong Typescript, dấu <code>@</code> cho ta biết đó là một <code>decoration</code>, nó giống như là metadata cho class.</p>
<ul>
<li>Đầu file, ta import <code>bootstrap</code> và <code>Component</code> từ thư viện angular2 để sử dụng. </li>
<li><code>@Component</code> cho Angular biết <code>AppComponent</code> là một component. Config object của <code>@Component</code> gồm 2 thuộc tính.<ul>
<li><code>selector</code>: CSS selector cho Angular biết component của chúng ta sẽ được áp dụng ở đâu. Như ví dụ trên nó sẽ áp dụng vào element `<my-app></my-app>‘</li>
<li><code>template</code>: Phần hiển thị của component. Tạm thời ta dùng inline code, sau này ta sẽ tách nó ra thành 1 file template riêng.</li>
</ul>
</li>
<li><code>bootstrap</code>: cho Angular biết component này là component gốc của ứng dụng. Sau này trong component gốc ta có thể có các component khác.</li>
</ul>
<h1 id="Nhung-cac-thu-vien-va-code-vao-file-index-html"><a href="#Nhung-cac-thu-vien-va-code-vao-file-index-html" class="headerlink" title="Nhúng các thư viện và code vào file index.html"></a>Nhúng các thư viện và code vào file index.html</h1><p>Trong file <code>index.html</code> ta có code như sau:</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">head</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>Angular 2 Quickstart<span class="tag">&lt;/<span class="name">title</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://code.angularjs.org/tools/system.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://code.angularjs.org/tools/typescript.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://code.angularjs.org/2.0.0-alpha.44/angular2.dev.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="actionscript"></span></div><div class="line">      System.config(&#123;</div><div class="line">        transpiler: <span class="string">'typescript'</span>,</div><div class="line">        typescriptOptions: &#123; emitDecoratorMetadata: <span class="literal">true</span> &#125;</div><div class="line">      &#125;);</div><div class="line">      System.import(<span class="string">'./app.ts'</span>);</div><div class="line">    <span class="tag">&lt;/<span class="name">script</span>&gt;</span></div><div class="line">  <span class="tag">&lt;/<span class="name">head</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">body</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">my-app</span>&gt;</span>loading...<span class="tag">&lt;/<span class="name">my-app</span>&gt;</span></div><div class="line">  <span class="tag">&lt;/<span class="name">body</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></div></pre></td></tr></table></figure>
<ul>
<li>Tạm thời ta sẽ không bàn về 3 thư viện ở trên cùng.</li>
<li>Trong đoạn config cho <code>System</code> (từ <code>system.js</code>, đây là một công cụ cho phép ta import code) ta yêu cầu chuyển đổi code từ <code>Typescript</code> sang <code>Javascript</code> ngay trên trình duyệt.</li>
<li>Import <code>AppComponent</code> của chúng ta từ file <code>app.ts</code></li>
<li>Trong <code>&lt;body&gt;</code> ta thêm một element <code>&lt;my-app&gt;</code>, chính là selector của <code>AppComponent</code> đã viết ở trên.</li>
</ul>
<h1 id="Chay-ung-dung"><a href="#Chay-ung-dung" class="headerlink" title="Chạy ứng dụng"></a>Chạy ứng dụng</h1><p>Để chạy ứng dụng ta cần 1 static file server, ở đây mình sẽ dung <code>live-server</code></p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">npm <span class="keyword">install</span> -g live-<span class="keyword">server</span></div><div class="line">cd /<span class="keyword">path</span>/<span class="keyword">to</span>/<span class="keyword">source</span></div><div class="line">live-<span class="keyword">server</span></div></pre></td></tr></table></figure>
<p><img src="/images/hello-angular2.png" alt="Hello Angular 2"></p>
<p>Chúc mừng, ứng dụng angular 2 đầu tiên của bạn đã hoàn thành.</p>
<h1 id="Cai-tien"><a href="#Cai-tien" class="headerlink" title="Cải tiến"></a>Cải tiến</h1><p>Ở đây có một vài phần chúng ta sẽ cần phải cải tiến cho ứng dụng của mình.</p>
<ol>
<li>Cấu trúc lại ứng dụng cho việc phát triển sau này</li>
<li>Sử dụng resource từ local thay vì tải từ mạng:<br>Tải resource từ trên mạng thì hiện tại vẫn ổn, nhưng trong quá trình dev mỗi lần ta reload lại trình duyệt ta sẽ mất thêm thời gian tải các resource từ mạng, vì vậy ta đưa các file resource về máy mình rồi tải lại sẽ nhanh hơn.</li>
<li>Chuyển đổi Typescript sang Javascript bằng công cụ thay vì trên trình duyệt:<br>Vì việc chuyển đổi thực hiện trên trình duyệt sẽ khiến cho ứng dụng của chúng ta trở nên chậm, khi có nhiều file cần phải xử lý. Vì vậy ta sẽ đổi sang javascript trước rồi mới để trình duyệt tải vào.</li>
<li>Sử dụng một vài công cụ cho việc dev (Như là công cụ để thực hiện mục 3)</li>
</ol>
<h2 id="Cau-truc-lai-ung-dung-cho-viec-phat-trien-sau-nay"><a href="#Cau-truc-lai-ung-dung-cho-viec-phat-trien-sau-nay" class="headerlink" title="Cấu trúc lại ứng dụng cho việc phát triển sau này"></a>Cấu trúc lại ứng dụng cho việc phát triển sau này</h2><p>Trong thư mục hiện tại, ta tạo thêm thư mục <code>src</code> và thư mục con của nó <code>app</code>. Di chuyển <code>index.html</code> vào thư mục <code>src</code> và <code>app.ts</code> vào thư mục <code>src/app</code>.</p>
<figure class="highlight gherkin"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">angular2</div><div class="line">  |<span class="string">- src</span></div><div class="line">      |<span class="string">- app</span></div><div class="line">      |<span class="string">   </span>|<span class="string">- app.ts</span></div><div class="line">      |<span class="string">- index.html</span></div></pre></td></tr></table></figure>
<h2 id="Cai-dat-cac-package-npm"><a href="#Cai-dat-cac-package-npm" class="headerlink" title="Cài đặt các package npm"></a>Cài đặt các package npm</h2><figure class="highlight css"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="selector-tag">npm</span> <span class="selector-tag">init</span> <span class="selector-tag">-y</span></div><div class="line"><span class="selector-tag">npm</span> <span class="selector-tag">i</span> <span class="selector-tag">angular2</span>@<span class="keyword">2</span>.<span class="keyword">0</span>.<span class="keyword">0</span>-<span class="keyword">alpha</span>.<span class="keyword">44</span> systemjs@<span class="number">0.19</span>.<span class="number">2</span> --save --save-exact</div><div class="line">npm i typescript live-server --save-dev</div></pre></td></tr></table></figure>
<ul>
<li><code>angular</code>: thư viện angular</li>
<li><code>systemjs</code>: hỗ trợ module loading</li>
</ul>
<p>Ngoài ra có 2 packages hỗ trợ cho việc dev</p>
<ul>
<li><code>typescript</code>: chuyển đổi typesript sang javascript</li>
<li><code>live-server</code>: static server tự động reload lại trang web khi file thay đổi</li>
</ul>
<p>Sau khi chạy lệnh cài đặt xong ta có file <code>package.json</code> như sau:</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line">&#123;</div><div class="line">  <span class="attr">"name"</span>: <span class="string">"angular2-quickstart"</span>,</div><div class="line">  <span class="attr">"version"</span>: <span class="string">"1.0.0"</span>,</div><div class="line">  <span class="attr">"description"</span>: <span class="string">""</span>,</div><div class="line">  <span class="attr">"main"</span>: <span class="string">"index.js"</span>,</div><div class="line">  <span class="attr">"scripts"</span>: &#123;</div><div class="line">    <span class="attr">"test"</span>: <span class="string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span></div><div class="line">  &#125;,</div><div class="line">  <span class="attr">"keywords"</span>: [],</div><div class="line">  <span class="attr">"author"</span>: <span class="string">""</span>,</div><div class="line">  <span class="attr">"license"</span>: <span class="string">"ISC"</span>,</div><div class="line">  <span class="attr">"dependencies"</span>: &#123;</div><div class="line">    <span class="attr">"angular2"</span>: <span class="string">"2.0.0-alpha.44"</span>,</div><div class="line">    <span class="attr">"systemjs"</span>: <span class="string">"0.19.2"</span></div><div class="line">  &#125;,</div><div class="line">  <span class="attr">"devDependencies"</span>: &#123;</div><div class="line">    <span class="attr">"live-server"</span>: <span class="string">"^0.8.2"</span>,</div><div class="line">    <span class="attr">"typescript"</span>: <span class="string">"^1.7.3"</span></div><div class="line">  &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>Tìm đến phần <code>scripts</code> sửa lại:</p>
<figure class="highlight xquery"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="string">"scripts"</span>: &#123;</div><div class="line">  <span class="string">"tsc"</span>: <span class="string">"tsc -p src -w"</span>,</div><div class="line">  <span class="string">"start"</span>: <span class="string">"live-server --open=src"</span></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h2 id="Cap-nhat-lai-file-index-html"><a href="#Cap-nhat-lai-file-index-html" class="headerlink" title="Cập nhật lại file index.html"></a>Cập nhật lại file index.html</h2><p>Nạp resource từ thư mục ta vừa cài các packages</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"../node_modules/systemjs/dist/system.src.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"../node_modules/angular2/bundles/angular2.dev.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></div></pre></td></tr></table></figure>
<p>Cập nhật lại cấu hình của <code>System</code></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="actionscript"></span></div><div class="line">  System.config(&#123;</div><div class="line">    packages: &#123;<span class="string">'app'</span>: &#123;defaultExtension: <span class="string">'js'</span>&#125;&#125;</div><div class="line">  &#125;);</div><div class="line">  System.import(<span class="string">'app/app'</span>);</div><div class="line"><span class="tag">&lt;/<span class="name">script</span>&gt;</span></div></pre></td></tr></table></figure>
<p>Vì bây giờ ta không chuyển đổi typescript ngay trên trình duyệt nữa, mà sẽ chạy lệnh chuyển đổi từ máy trước, nên trên trình duyệt ta chỉ nạp các file js.</p>
<h2 id="Cau-hinh-cho-viec-bien-dich-typescript"><a href="#Cau-hinh-cho-viec-bien-dich-typescript" class="headerlink" title="Cấu hình cho việc biên dịch typescript"></a>Cấu hình cho việc biên dịch typescript</h2><p>Trong thư mục <code>src</code> ta thêm file <code>tsconfig.json</code> với nội dung như sau:</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line">&#123;</div><div class="line">  <span class="attr">"compilerOptions"</span>: &#123;</div><div class="line">    <span class="attr">"target"</span>: <span class="string">"ES5"</span>,</div><div class="line">    <span class="attr">"module"</span>: <span class="string">"commonjs"</span>,</div><div class="line">    <span class="attr">"sourceMap"</span>: <span class="literal">true</span>,</div><div class="line">    <span class="attr">"emitDecoratorMetadata"</span>: <span class="literal">true</span>,</div><div class="line">    <span class="attr">"experimentalDecorators"</span>: <span class="literal">true</span>,</div><div class="line">    <span class="attr">"removeComments"</span>: <span class="literal">false</span>,</div><div class="line">    <span class="attr">"noImplicitAny"</span>: <span class="literal">false</span></div><div class="line">  &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>Bạn có thể xem thêm các tùy chọn tại đây <a href="https://github.com/Microsoft/TypeScript/wiki/tsconfig.json" target="_blank" rel="external">Typescript config</a></p>
<h2 id="Bien-dich-typescript-sang-javascript"><a href="#Bien-dich-typescript-sang-javascript" class="headerlink" title="Biên dịch typescript sang javascript"></a>Biên dịch typescript sang javascript</h2><p>Di chuyển đến thư mục gốc của ứng dụng, chạy lệnh <code>tsc</code> mà ta vừa thêm vào <code>package.json</code> ở trên:</p>
<figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm <span class="keyword">run</span><span class="bash"> tsc</span></div></pre></td></tr></table></figure>
<p>Sau khi chạy, ta sẽ thấy trong thư mục <code>src/app</code> có thêm file <code>app.js</code> và <code>app.js.map</code> file này giúp ích cho ta trong việc debug giữa file javascript và file typescript. Vì đã thêm tham số <code>-w</code> nên câu lệnh sẽ tiếp tục <code>watch</code>-theo dõi các file typescript, khi có thay đổi nó sẽ tự biên dịch lại. Bạn cứ để nó chạy ở đó, nếu muốn dừng thì nhấn <code>Ctrl+C</code>.</p>
<h2 id="Chay-ung-dung-1"><a href="#Chay-ung-dung-1" class="headerlink" title="Chạy ứng dung"></a>Chạy ứng dung</h2><p>Mở một cửa sổ terminal khác, di chuyển đến thư mục gốc của ứng dụng và chạy lệnh:</p>
<figure class="highlight coffeescript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">npm</span> start</div></pre></td></tr></table></figure>
<p>Và trình duyệt lại chạy lên, hiển thị ứng dụng của chúng ta với chữ <strong>“Hello Angular2”</strong></p>
<h2 id="Thay-doi-noi-dung"><a href="#Thay-doi-noi-dung" class="headerlink" title="Thay đổi nội dung"></a>Thay đổi nội dung</h2><p>Như đã nói ở trên, công cụ biên dịch typescript của chúng ta sẽ tự động biên dịch lại khi nội dung file thay đổi, và live-server cũng tự động tải lại trang khi nội dung file thay đổi. Bây giờ bạn vào file <code>app.ts</code> thử thay đổi lại <code>template</code> của component và xem trình duyệt tự động cập nhật lại nội dung cho bạn như thế nào.</p>
<h1 id="Tong-ket"><a href="#Tong-ket" class="headerlink" title="Tổng kết"></a>Tổng kết</h1><ul>
<li>Angular 2 có phần quan trọng nhất là <code>Component</code></li>
<li>Ta có thể dùng Typescript để viết ứng dụng với Angular 2 và biên dịch ra javascript bằng <strong>T</strong>ype<strong>s</strong>cript <strong>C</strong>ompiler (TSC)</li>
<li>Bằng cách để Compiler theo dõi file và sử dụng live-server ta có thể thấy được ứng dụng thay đổi nhanh chóng sau khi thay đổi code</li>
<li>Đây chỉ là một ứng dụng rất đơn giản, để làm quen với Angular 2</li>
</ul>
<p>Các thao tác trong bài này mình hoàn toàn theo bài hướng dẫn tại <a href="https://angular.io/docs/ts/latest/quickstart.html" target="_blank" rel="external">Angular Quickstart</a> các bạn có thể đọc để nắm thêm chi tiết.</p>
<h1 id="Trinh-duyet-ho-tro-ES6"><a href="#Trinh-duyet-ho-tro-ES6" class="headerlink" title="Trình duyệt hỗ trợ ES6"></a>Trình duyệt hỗ trợ ES6</h1><p>Angular 2 yêu cầu trình duyệt hỗ trợ ES6, hầu hết đều đã được hỗ trợ với các trình duyệt hiện tại. Tuy nhiên với các trình duyệt cũ hơn như IE11 ta có thể dùng thêm thư viện <code>shim</code></p>
<p>Cài đặt <code>shim</code></p>
<figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm <span class="keyword">install </span>es6-<span class="keyword">shim </span>--save</div></pre></td></tr></table></figure>
<p>Thêm vào <code>index.html</code></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"../node_modules/es6-shim/es6-shim.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></div></pre></td></tr></table></figure>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Angular2 hiện tại vẫn đang trong giai đoạn &lt;code&gt;Developer Preview&lt;/code&gt; tuy nhiên mình sẽ bắt đầu tìm hiểu trước cho đến khi nó được &lt;code&gt;release&lt;/code&gt; thì dùng luôn. Hiện tại trên trang của Angular2 thấy chúng ta có thể code bằng &lt;code&gt;Javascript&lt;/code&gt;, &lt;code&gt;Typescript&lt;/code&gt; và &lt;code&gt;Dart&lt;/code&gt;, nhưng xem qua các bài hướng dẫn thì mọi người có vẻ dùng &lt;code&gt;Typescript&lt;/code&gt; phổ biến hơn. Nên mình cũng sẽ làm quen với Angular2 bằng Typescript luôn.&lt;/p&gt;
&lt;p&gt;Trong phần làm quen này, chúng ta cùng nhau viết ứng dụng vô cùng đơn giản coi như để biết được Angular2 là cái gì, và viết nó như thế nào. Một ứng dụng Hello World.&lt;/p&gt;
    
    </summary>
    
    
      <category term="Angular2" scheme="http://saysua.com/tags/Angular2/"/>
    
  </entry>
  
  <entry>
    <title>Lowdb - DB không cần server</title>
    <link href="http://saysua.com/2015/09/30/lowdb-DB-khong-can-server/"/>
    <id>http://saysua.com/2015/09/30/lowdb-DB-khong-can-server/</id>
    <published>2015-09-30T02:34:51.000Z</published>
    <updated>2016-10-16T01:42:23.797Z</updated>
    
    <content type="html"><![CDATA[<p>Từ yêu cầu cá nhân, mình cần  tạo một server API giả bằng nodejs để phục vụ cho việc làm frontend. Mình có ý muốn tìm một thư viện DB nhỏ gọn, dễ cài đặt sử dụng, hỗ trợ JSON, chỉ dựa trên file text đơn giản, chứ không cần phải cài đặt server như mongoDB và nếu thao tác giống như mongoDB thì tốt.</p>
<p>Sau một hồi dạo quanh thì mình đã tìm thấy <a href="https://github.com/typicode/lowdb" target="_blank" rel="external">LowDB</a></p>
<blockquote><p>Need a quick way to get a local database?</p>
</blockquote>
<a id="more"></a>
<h1 id="Cai-dat"><a href="#Cai-dat" class="headerlink" title="Cài đặt"></a>Cài đặt</h1><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm <span class="keyword">install</span> lowdb <span class="comment">--save</span></div></pre></td></tr></table></figure>
<h1 id="Su-dung"><a href="#Su-dung" class="headerlink" title="Sử dụng"></a>Sử dụng</h1><figure class="highlight stylus"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="selector-tag">var</span> low = require(<span class="string">'lowdb'</span>)</div><div class="line"><span class="selector-tag">var</span> db = low(<span class="string">'db.json'</span>)</div><div class="line"></div><div class="line"><span class="function"><span class="title">db</span><span class="params">(<span class="string">'posts'</span>)</span></span>.push(&#123; title: <span class="string">'lowdb is awesome'</span>&#125;)</div></pre></td></tr></table></figure>
<p>Ở đây, dự liệu sẽ được tự động lưu vào file <code>db.json</code></p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">&#123;</div><div class="line">  <span class="attr">"posts"</span>: [</div><div class="line">    &#123; <span class="attr">"title"</span>: <span class="string">"lowdb is awesome"</span> &#125;</div><div class="line">  ]</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h1 id="Mot-vai-thao-tac-su-dung-co-ban"><a href="#Mot-vai-thao-tac-su-dung-co-ban" class="headerlink" title="Một vài thao tác sử dụng cơ bản"></a>Một vài thao tác sử dụng cơ bản</h1><p><code>LowDB</code> này sử dụng <code>lodash</code>, nên thao tác với API của nó cũng giống như thao tác với API của <code>lodash</code> vậy.</p>
<h2 id="Them-du-lieu"><a href="#Them-du-lieu" class="headerlink" title="Thêm dữ liệu"></a>Thêm dữ liệu</h2><figure class="highlight less"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="selector-tag">db</span>(<span class="string">'users'</span>)<span class="selector-class">.push</span>(&#123; <span class="attribute">name</span>: <span class="string">'Thach Nguyen'</span>, <span class="attribute">email</span>: <span class="string">'thach@email.com'</span>, <span class="attribute">role</span>: <span class="string">'admin'</span>&#125;);</div></pre></td></tr></table></figure>
<h2 id="Tim-1-doi-tuong"><a href="#Tim-1-doi-tuong" class="headerlink" title="Tìm 1 đối tượng"></a>Tìm 1 đối tượng</h2><figure class="highlight less"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="selector-tag">db</span>(<span class="string">'users'</span>)<span class="selector-class">.find</span>(&#123;<span class="attribute">email</span>: <span class="string">'thach@email.com'</span>&#125;);</div></pre></td></tr></table></figure>
<h2 id="Tim-nhieu-doi-tuong"><a href="#Tim-nhieu-doi-tuong" class="headerlink" title="Tìm nhiều đối tượng"></a>Tìm nhiều đối tượng</h2><figure class="highlight stylus"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="title">db</span><span class="params">(<span class="string">'users'</span>)</span></span>.<span class="attribute">filter</span>(&#123;role: <span class="string">'admin'</span>&#125;);</div></pre></td></tr></table></figure>
<h2 id="Cap-nhat-du-lieu"><a href="#Cap-nhat-du-lieu" class="headerlink" title="Cập nhật dữ liệu"></a>Cập nhật dữ liệu</h2><figure class="highlight less"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="selector-tag">db</span>(<span class="string">'users'</span>)</div><div class="line">  <span class="selector-class">.chain</span>()</div><div class="line">  <span class="selector-class">.find</span>(&#123;<span class="attribute">email</span>: <span class="string">'thach@email.com'</span>&#125;)</div><div class="line">  <span class="selector-class">.assign</span>(&#123;<span class="attribute">role</span>: <span class="string">'member'</span>&#125;)</div><div class="line">  <span class="selector-class">.value</span>();</div></pre></td></tr></table></figure>
<h2 id="Xoa-du-lieu"><a href="#Xoa-du-lieu" class="headerlink" title="Xóa dữ liệu"></a>Xóa dữ liệu</h2><figure class="highlight less"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="selector-tag">db</span>(<span class="string">'users'</span>)<span class="selector-class">.remove</span>(&#123;<span class="attribute">role</span>: <span class="string">'member'</span>&#125;);</div></pre></td></tr></table></figure>
<h2 id="Lay-so-luong-users"><a href="#Lay-so-luong-users" class="headerlink" title="Lấy số lượng users"></a>Lấy số lượng users</h2><figure class="highlight less"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="selector-tag">db</span>(<span class="string">'users'</span>)<span class="selector-class">.size</span>();</div></pre></td></tr></table></figure>
<h2 id="Ho-tro-ID"><a href="#Ho-tro-ID" class="headerlink" title="Hỗ trợ ID"></a>Hỗ trợ ID</h2><p>Có 2 cách tạo ID cho dữ liệu.</p>
<ul>
<li>Sử dụng <a href="https://github.com/typicode/underscore-db" target="_blank" rel="external">underscore-db</a></li>
</ul>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="selector-tag">var</span> db = low(<span class="string">'db.json'</span>)</div><div class="line"></div><div class="line">db._.mixin(require(<span class="string">'underscore-db'</span>))</div><div class="line"></div><div class="line"><span class="selector-tag">var</span> songId = db(<span class="string">'songs'</span>).insert(&#123; title: <span class="string">'low!'</span> &#125;)<span class="selector-class">.id</span></div><div class="line"><span class="selector-tag">var</span> song   = db(<span class="string">'songs'</span>).getById(songId)</div></pre></td></tr></table></figure>
<ul>
<li>Dùng <a href="https://github.com/broofa/node-uuid" target="_blank" rel="external">uuid</a></li>
</ul>
<figure class="highlight qml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">var</span> uuid = <span class="built_in">require</span>(<span class="string">'uuid'</span>)</div><div class="line"></div><div class="line"><span class="built_in">var</span> songId = db(<span class="string">'songs'</span>).push(&#123; <span class="attribute">id:</span><span class="string"> uuid</span>(), <span class="attribute">title</span>: <span class="string">'low!'</span> &#125;).id</div><div class="line"><span class="built_in">var</span> song   = db(<span class="string">'songs'</span>).find(&#123; <span class="attribute">id:</span><span class="string"> songId</span> &#125;)</div></pre></td></tr></table></figure>
<h1 id="Ket"><a href="#Ket" class="headerlink" title="Kết"></a>Kết</h1><p>Theo tác giả của lowDB thì:</p>
<p>Nếu các bạn muốn tìm một DB nhanh gọn, không cần cài đặt server thì <code>lowdb</code> này là một lựa chọn hợp lý. Còn bình thường thì cứ dùng MongoDB hoặc các DB khác. :)</p>
<p>Các bạn có thể đọc thêm cách sử dụng ở đây: <a href="https://github.com/typicode/lowdb" target="_blank" rel="external">https://github.com/typicode/lowdb</a></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Từ yêu cầu cá nhân, mình cần  tạo một server API giả bằng nodejs để phục vụ cho việc làm frontend. Mình có ý muốn tìm một thư viện DB nhỏ gọn, dễ cài đặt sử dụng, hỗ trợ JSON, chỉ dựa trên file text đơn giản, chứ không cần phải cài đặt server như mongoDB và nếu thao tác giống như mongoDB thì tốt.&lt;/p&gt;
&lt;p&gt;Sau một hồi dạo quanh thì mình đã tìm thấy &lt;a href=&quot;https://github.com/typicode/lowdb&quot;&gt;LowDB&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Need a quick way to get a local database?&lt;/p&gt;
&lt;/blockquote&gt;
    
    </summary>
    
    
      <category term="Nodejs" scheme="http://saysua.com/tags/Nodejs/"/>
    
  </entry>
  
  <entry>
    <title>Import mysql từ file zip</title>
    <link href="http://saysua.com/2015/09/08/import-mysql-tu-file-zip/"/>
    <id>http://saysua.com/2015/09/08/import-mysql-tu-file-zip/</id>
    <published>2015-09-08T04:05:24.000Z</published>
    <updated>2016-10-16T01:41:15.387Z</updated>
    
    <content type="html"><![CDATA[<p>Vừa rồi mình phải import dữ liệu mysql từ một file zip khoảng 700MB nhưng khi giải nén ra thì đến 4GB lận. Để import quả là không đơn giản. Và rồi cũng đã tìm được 1 cách import với chỉ 1 câu lệnh:</p>
<figure class="highlight 1c"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">unzip -p dbdump.sql.zip <span class="string">| mysql -u root -p dbname</span></div></pre></td></tr></table></figure>
<ul>
<li>Câu lệnh này chỉ thực hiện được với điều kiện file zip của bạn chỉ có 1 file sql.</li>
<li>Thay <code>root</code> bằng user mysql của bạn</li>
<li>Thay <code>dbname</code> bằng tên của DB</li>
<li>Nhập password vào và chờ kết thúc.</li>
</ul>
<p>Cách này mình tìm được từ đây: <a href="http://snippets.khromov.se/import-zipped-mysql-dumps/" target="_blank" rel="external">http://snippets.khromov.se/import-zipped-mysql-dumps/</a></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Vừa rồi mình phải import dữ liệu mysql từ một file zip khoảng 700MB nhưng khi giải nén ra thì đến 4GB lận. Để import quả là không đơn giả
    
    </summary>
    
    
      <category term="Mysql" scheme="http://saysua.com/tags/Mysql/"/>
    
  </entry>
  
  <entry>
    <title>Tạm biệt wordpress xin chào hexo</title>
    <link href="http://saysua.com/2015/08/27/tam-biet-wordpress-xin-chao-hexo/"/>
    <id>http://saysua.com/2015/08/27/tam-biet-wordpress-xin-chao-hexo/</id>
    <published>2015-08-27T00:05:20.000Z</published>
    <updated>2016-10-15T09:27:50.958Z</updated>
    
    <content type="html"><![CDATA[<p>Như vậy là sau vài lần tìm kiếm và thử nghiệm, cuối cùng cũng đã tìm ra một cách viết blog mới để thay thế cho em wordpress. Với sở thích đơn giản, thích nghịch ngợm nên với mình wordpress tỏ ra cồng kềnh nhiều tính năng không dùng đến. Mình muốn một cách viết blog đơn giản như là dùng markdown để viết, không cần dùng cơ sở dữ liệu, tận dụng được hosting đang có.</p>
<a id="more"></a>
<p>Trước đây mình đã thử với một sản phẩm viết blog bằng python, sau khi viết xong nó tự động generate ra các file html rồi up lên host. Nhưng mà python thì mình cũng không thích lắm, muốn một cái tương tự bằng node. Và rồi mình tìm thấy <a href="https://hexo.io/" target="_blank" rel="external">hexo</a></p>
<blockquote><p>A fast, simple &amp; powerful blog framework</p>
</blockquote>
<p>Giới thiệu chung thì đây là một nền tảng viết blog bằng nodejs:</p>
<ul>
<li>Viết bài bằng markdown</li>
<li>Có giả lập server để test trên localhost</li>
<li>Tự động generate ra file html</li>
<li>Có các tùy chọn để deploy qua git, fpt, ssh</li>
</ul>
<p>Khi viết thì chỉ cần tạo ra một file <code>.md</code>, dùng một phần mềm editor bất kỳ để viết nội dung rồi sau đó deploy.</p>
<p>Có khi các bạn nhìn vào thấy nó phức tạp hơn wordpress nhiều nhưng bản thân mình thì thấy nó rất thú vị và quyết định đưa em <code>hexo</code> vào đội.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Như vậy là sau vài lần tìm kiếm và thử nghiệm, cuối cùng cũng đã tìm ra một cách viết blog mới để thay thế cho em wordpress. Với sở thích đơn giản, thích nghịch ngợm nên với mình wordpress tỏ ra cồng kềnh nhiều tính năng không dùng đến. Mình muốn một cách viết blog đơn giản như là dùng markdown để viết, không cần dùng cơ sở dữ liệu, tận dụng được hosting đang có.&lt;/p&gt;
    
    </summary>
    
    
  </entry>
  
</feed>
