PHP Ionic Angularjs Phonegap AJAX Javascript CSS MySQL jQuery Forum

สร้าง todo app กับการศึกษา angularjs ตอนที่ 2

11 August 2014 By


เนื้อหาในตอนที่ 2 จะยากขึ้นมาหน่อย แต่จะได้ศึกษา ส่วนใช้งาน
เพิ่มขึ้น todo app คือ การทำ ลิสรายการที่ต้องทำ ก็จะอ้างอิง ตัวอย่าง
จากเว็บไซต์ https://angularjs.org/ เช่นดิม

เนื้อหาก่อนหน้า
เรียนรู้ angularjs javascript framework ตอนที่ 1 
http://www.ninenik.com/content.php?arti_id=514 via @ninenik
 
เริ่มต้น ไฟล์ ทดสอบครั้งนี้ มีด้วยกัน 3 ไฟล์ คือ
index.html  สำหรับทดสอบ แสดงผล
todo.js  สำหรับเขียน javascript 
todo.css สำหรับจัดรูปแบบ html
 
มีอะไรเพิ่มมา ในไฟล์ index.html 
 
<!DOCTYPE html>
<html ng-app="todoApp">
  <head>
    <meta charset="utf-8" />  
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.17/angular.min.js"></script>
    <script src="todo.js"></script>
    <link rel="stylesheet" href="todo.css"> 
    <title>My Learn AngularJs 2</title> 
  </head>
  <body>

    <h2>Todo</h2>
    <div ng-controller="TodoController">
      <span>{{remaining()}} of {{todos.length}} remaining</span>
      [ <a href="" ng-click="archive()">archive</a> ]
      <ul class="unstyled">
        <li ng-repeat="todo in todos">
          <input type="checkbox" ng-model="todo.done">
          <span class="done-{{todo.done}}">{{todo.text}}</span>
        </li>
      </ul>
      <form ng-submit="addTodo()">
        <input type="text" ng-model="todoText"  size="30"
               placeholder="add new todo here">
        <input class="btn-primary" type="submit" value="add">
      </form>
    </div> 

    
  </body>
</html>
 
1. จะเห็นว่า ในบรรทัดที่ 2 จะมีการกำหนดค่าให้กับ attribute (directive ใน angularjs) ng-app ซึ่งปกติหาก
ไม่มีการกำหนดค่า ให้เข้าใจว่า angularjs จะทำงานกับทั้งหน้าเพจนั้น และการ
กำหนดค่า ให้กับ ng-app ก็เพื่อสำหรับอ้างอิงการเรียกใช้งาน 
 
<html ng-app="todoApp">
 
ในการทำ todo app จึงมีการตั้งชื่อเป็น todoApp
กำหนดชื่อแบบ camelCase คือ คำตัวเล็กตัวใหญ่สลับกัน คล้ายหลังอูฐ)
 
2. บรรทัดที่ 6 โหลดไฟล์ javascirpt todo.js ไฟล์นี้เราจะสร้างขึ้นมา และก็ใช้สำหรับ
กำหนดการทำงานของ todo app 
 
3. บรรทัดที่ 7 โหลดไฟล์ css ไฟล์นี้ สร้างขึ้นมา ไม่มีอะไรมาก เป้นแค่การกำหนด style
ให้กับ รายการที่ถูกเลือกแล้ว ให้มี เส้นขึดฆ่า และเป็นข้อความสีเทา 
 
โฟล์ todo.css
 
.done-true { /*  ชื่อ class สำหรับรายการที่ถูกติ้กเลือก */
  text-decoration: line-through; /*  แสดงเส้นขีดฆ่า */
  color: grey;  /* แสดงเป็นสีเทา */
}
ul.unstyled{ /*  ชื่อ class สำหรับรายการ แสดงลิสรายการ  */
margin: 0;
padding:5px;
list-style: none;
}
 
4. บรรทัดที่ 13 มี attribute (directive ใน angularjs) ใหม่ คือ ng-controller ให้เข้าใจว่า เป็นการกำหนดชื่อ
class ซึ่งจะมีการเรียกใช้งาน ในที่นี้เขากำหนดเป็นชื่อ TodoController
 
 <div ng-controller="TodoController">
 
หลักการสำหรับใช้งานคือ การกระทำใดๆ ก็ตามที่เกิดขึ้นภายในส่วนนี้ จะถูกเรียกใช้ผ่าน
class ที่ชื่อ  TodoController
 
5. บรรทัดที่ 14 เป็นการวาง template หรือจัดรูปแบบสำหรับการแสดงผล
โดยอย่าลืมว่า จะใช้ในลักษณะ ปีกกาปิดปิดอย่างละสองอัน {{}} 
ด้านในเป็นได้ทั้งชื่อฟังก์ชัน ค่า object หรือชื่อตัวแปร เป็นต้น สำหรับอ้างอิง
 
<span>{{remaining()}} of {{todos.length}} remaining</span>
 
จากโค้ดบรรทัดนี้ จะเห็นว่า 
remaining() คือฟังก์ชั่น 
todos.length  คือค่าของ objext ชื่อ todos (ในไฟล์ todo.js จะอธิบายที่มาอีกที)
 
6. บรรทัดที่ 15 มี attribute (directive ใน angularjs) คือ ng-click ให้เข้าใจว่า ตัวนี้คล้าย กับ event onclick
หรือก็คือ เมื่อคลิก ก็จะเรียกใช้ฟังก์ชั่นด้านใน ชื่อ archive() โดยฟังก์ชั่นนี้ ก็คือการ
จัดเก็บรายการที่ถูกติ้กเลือกแล้ว ในตัวอย่างเป็นแค่การลบออกธรรมา
 
  [ <a href="" ng-click="archive()">archive</a> ]
 
7. บรรทัดที่ 16-21 ก็จะเป็น แท็ก html คล้ายกับการวาง template การแสดงข้อมูล
เหตุที่ใช้แท็ก ul ก็เพื่อรองรับ การทำงานในลักษณะวนลูป หรือซ้ำการแสดงข้อมูล
แบบเป็นลิสรายการ 
 
จะเห็นว่า บรรทัดที่ 17 จะมีการกำหนด ng-repeat ให้เข้าใจว่า จะมีการวนลูปแสดง หรือ
การแสดงข้อมูลแท็ก li นี้ซ้ำ ตามจำนวนลิสรายการ เช่นถ้ามีการเพิ่ม รายการเข้าไป ก็จะ
มีการแสดง li แทรกเข้ามา และหากมีการลบ ก็จะทำการลบแท็ก li ออกไป 
 
<li ng-repeat="todo in todos">
 
สังเกตการกำหนดค่า ng-repeat เป็น "todo in todos"
todo คือค่า instnant หรือ object อ้างอิง ของ property ชื่อ todos อีกที 
(todos จะมีอธิบายในไฟล์ todo.js)
 
บรรทัดที่ 18 บรรทัดนี้ เราจะพบ ng-model ซึ่งได้รู้จักคร่าวๆ มาแล้วในตอนที่ 1
 
<input type="checkbox" ng-model="todo.done">
 
ให้เข้าใจว่า ค่าของ checkbox นี้ มีค่าเท่ากับ ค่าของ todo.done
เช่น todo.done มีค่าเท่ากับ true แล้ว checkbox ก็จะถูกติ้กเลือก
แต่ถ้า todo.don มีค่าเท่ากับ false แล้ว checkbox ก็จะไม่ถุกเลือก เป็นต้น
 
บรรทัดที่ 19 ส่วนนี้ไม่มีอะไร จะเป็นแค่กำหนด template ของการแสดงข้อความ
ตามค่าที่ได้ 
 
<span class="done-{{todo.done}}">{{todo.text}}</span>
 
สังเกตแท็ก span นี้ ถ้า todo.done มีค่าเท่ากับ true ก็จะทำให้
class css ของ span ก็จะมีชื่อเป็น done-true ซึ่งก็คือ css ขัดฆ่าในไฟล์ todo.css นั่นเอง
สำหรับ todo.text ก็คือ ข้อความของรายการ ที่แสดงในแท็ก span
 
 
8. บรรทัดที่ 22-26 เป็นส่วนของ form สำหรับส่งข้อมูล ในที่นี้ คือการเพิ่ม
ลิ้สรายการ todo มี attibute สำหรับการ submit form คือ ng-submit คล้ายกับ
event submit หรือเหตุการเมื่อมีการกดปุ่มส่ง submit ข้อมูล ตามตัวอย่าง ก็จะไป
เรียกใช้ฟังก์ชั่น addTodo()
 
 <form ng-submit="addTodo()">
 
บรรทัดที่ 23 input text สำหรับรับค่าลิ้สรายการ โดยใช้ ng-model กำหนดให้ค่าของ 
input text นี้อยู่ในชื่อ todoText 
 
บรรทัดที่ 25 ปุ่ม กำหนดให้เป็น type submit  เพื่อให้ event submit ทำงาน

 
9 ส่วนสุดท้าย อันนี้ยากหน่อย มาลองๆ ดูกัน
ไฟล์ toto.js คือส่วนการของการคำสั่ง และการกำหนดให้ทำงานทั้งหมด
คำอธิบายแสดงใน โค้ด
 
โค้ดไฟล์ todo.js
 
angular.module('todoApp', []) /*  angularjs จะเข้ามาจัดการในส่วนที่กำหนดนี้ <html ng-app="todoApp"> */
  .controller('TodoController', ['$scope', function($scope) 
  {/*  โดยเข้ามาจัดการเหตุการณ์ ต่างๆ ใน <div ng-controller="TodoController"> ผ่าน $scope object */
  
/* 	ส่วนนี้ จะเป็นการกำหนดรายการ todo สองรายการเริ่มต้น
	โดย todos คือชื่อ property ของ object scope
	ใน todos property ก็จะมี name และ value  */
    $scope.todos = [ /*   todos นี้มี property type เป็นแบบ array มี name ชื่อ text และ done   */
      {text:'learn angular', done:true},
      {text:'build an angular app', done:false}
	];
/* 	เมื่อมีการโหลดหน้า app เพจ เริ่มต้น สอง รายการด้านบนนี้
	จะถูกนำไปแสดงในแท็ก li ผ่าน ng-repeat  ตาม html ด้านล่าง
	todo จะไปเรียกใช้งาน property todos ของ object scope ผ่านค่า todo in todos
	iรายการแรก จะถูกติ้กเลือก เพราะ มีค่า todo.done = todos.done = true
	และรายการ ข้อความใน span จะถูกขีดฆ่า ด้วย css class
	done-{{todo.done}} = done-{{todos.done}}  = done-true
	{{todo.text}}  = todos.text 
         <li ng-repeat="todo in todos">
          <input type="checkbox" ng-model="todo.done">
          <span class="done-{{todo.done}}">{{todo.text}}</span>
        </li> */
 
 
/* 	object scope กำหนด method ขอเรียกเป็น ฟังก์ชั่นละกัน
	ฟังก์ชั่น addTodo() 
	เนื่องจาก property todos เป็น array การเพิ่มข้อมูลเข้าไปจะใช้ คำสั่ง push เพื่อเพิ่ม array
	<input type="text" ng-model="todoText"  size="30"
		   placeholder="add new todo here">	
	จะเห็นว่า object scope จะดึงค่า input text ด้วยชื่อ 	todoText โดยเรียกผ่าน $scope.todoText 
	การเพิ่มค่า จะเพิ่มเข้าไป สองค่า คือ text กับ done 
	ค่า text คือค่า จาก input text ส่วนค่า done จะเป็นค่าเริ่มต้น กำหนดให้เป็น false คือยังไม่ถูกติ้กเลือก	 */
    $scope.addTodo = function() {
      $scope.todos.push({text:$scope.todoText, done:false}); /*  เพิ่มค่าเข้าไปใน array todos */
      $scope.todoText = ''; /* หลังจากเพิ่มค่าแล้ว ให้ลบข้อความ ใน input text */
    };
 
	
/* 	ส่วนของการแสดงค่า จำนวนรายการ ใน template 
    <span>{{remaining()}} of {{todos.length}} remaining</span>
	โดย todos.length คือ จะนับค่า รายการใน array todos ทั้งหมด ส่งค่าไปแสดง
	สำหรับรายการที่ยังไม่ติ้กเลือก หรือรายการคงเหลือ
	จะใช้ฟังก์ชั่น remaining() */
    $scope.remaining = function() {
      var count = 0;  // กำหนดตัวแปร ค่านับเริ่มต้น เป็น 0
      angular.forEach($scope.todos, function(todo) {  //คำสั่งของ angularjs วนลูปแสดง array todos
		//ให้ตัวนับจำนวนทั้งหมด บวกค่า ตามเงือนไข
        count += todo.done ? 0 : 1; // นับเฉพาะรายการ false หรือรายการยังไม่ติ้กเลือก ให้บวกเพิ่ม ทีละ 1
      });
      return count; // คืนค่า รายการที่ยังไม่ถูกติ้กเลือกทั้งหมด หรือรายการคงเหลือ
    };
 
/* 	ส่วนสุดท้าย กับการใช้งานกับ event click เพื่อกำหนดรายการเป็น archive 
	ที่จริงก็คือรายการลิ้สที่ติ้กเลือกแล้ว และต้องการจัดเก็บ แต่คำสั่ง จะเป็นการลบออก เพื่อดูผลลัพธ์อย่างง่าย
     [ <a href="" ng-click="archive()">archive</a> ]
	จะใช้งาน ฟังก์ชั่น archive()
	โดยในตัวอย่างนี้ เขาจะกำหนด property todos ที่เป็น array ของ object scope
	ด้วย $scope.todos = []; กำหนดเป็น array ค่าว่าง
	แล้วเพิ่มค่าไปใหม่ */
    $scope.archive = function() {
      var oldTodos = $scope.todos;  // เก็บค่า todos array ทั้งหมดไว้กับตัวแปร array oldTodos แทนก่อน
      $scope.todos = []; // ล้างค่าตัวเก่า โดย กำหนดเป็น array ค่าว่าง
      angular.forEach(oldTodos, function(todo) { // นำค่าที่ถูกเก็บในตัวแปร oldTodos วนลูปแสดง
		// จากนั้น เพิ่มค่าเข้าไปใหม่ ภายในเงื่อนไขว่า เอาเฉพาะ รายการที่ยังไม่ถูกเลือกเท่านั้นไว้
		// ซื่อก็คือ รายการที่ todo.done=false ให้เอามาแสดง รายการที่ถูกเลือกแล้ว ไม่เอา
        if (!todo.done) $scope.todos.push(todo); // รายการที่ todo.done=false ให้เอามาแสดง
      });
	  
	  
    };
  }]);
 
แบบไม่มีคำอธิบาย โค้ดไฟล์ todo.js

angular.module('todoApp', [])
  .controller('TodoController', ['$scope', function($scope) {
    $scope.todos = [
      {text:'learn angular', done:true},
      {text:'build an angular app', done:false}];
 
    $scope.addTodo = function() {
      $scope.todos.push({text:$scope.todoText, done:false});
      $scope.todoText = '';
    };
 
    $scope.remaining = function() {
      var count = 0;
      angular.forEach($scope.todos, function(todo) {
        count += todo.done ? 0 : 1;
      });
      return count;
    };
 
    $scope.archive = function() {
      var oldTodos = $scope.todos;
      $scope.todos = [];
      angular.forEach(oldTodos, function(todo) {
        if (!todo.done) $scope.todos.push(todo);
      });
    };
  }]);

ตัวอย่าง

 
ตอนที่ 2 ยาว แต่ถ้าทำความเข้าใจ ก็จะเรียนรู้ได้เร็วขึ้น
ตอนนี้ได้รู้จัก ng-controller ng-click ng-submit ng-repeat 
และรู้จัก object scope เพิ่มเข้ามา 
 
ตอนหน้าจะมีอะไรใหม่ รอติดตาม
 
 
 
 
 



เนื้อหาที่เกี่ยวข้อง



Tags:: javascript angularjs





URL สำหรับอ้างอิง