วันจันทร์ที่ 28 กันยายน พ.ศ. 2558

AngularJS with Dependencies

Dependency Injection คือ รูปแบบการออกแบบโปรแกรมที่เกี่ยวข้องกับ Component โดยการอ้างอิงไปยัง Component ที่ต้องการ เช่น Service, Directive เป็นต้น

ข้อดีของการใช้ Dependency คือ สามารถเรียกใช้งาน Module ที่เขียนแยกไว้ตามหน้าที่เฉพาะอย่าง


ไฟล์ bookstore.html

<!DOCTYPE html>

<html ng-app="myapp">

<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
<script type="text/javascript" src="app.js"></script>

</head>

<body>
<book-type></book-type>
<book-author></book-author>
<book-title></book-title>
</body>

</html>


อธิบาย :
  • <book-type>,<book-author>,<book-title> คือ Custom Directive ที่สร้างขึ้น


ไฟล์ app.js


(function(){
var app = angular.module('myapp',[]);
app.directive('bookType',function(){
return{
restrict:'E',
templateUrl:'booktype.html',
controller:function(){
this.booktype = ['accounting','it','engineering'];
},
controllerAs:'Type'
};
});
app.directive('bookAuthor',function(){
return{
restrict:'E',
templateUrl:'bookauthor.html',
controller:function(){
this.bookauthor = ['Torben Lage Frandsen','Stephen Moffat','Steve Bark'];
},
controllerAs:'Author'
};
});
app.directive('bookTitle',function(){
return{
restrict:'E',
templateUrl:'booktitle.html'
};
});
})();


อธิบาย :
  • สร้าง Directive ที่เป็น HTML Element ชื่อ bookType, bookAuthor, bookTitle ( อ่านเพิ่มเติมจากบทความ AngularJS with Custom Directive )


ไฟล์ booktype.html


<select>
<option ng-repeat="book in Type.booktype" value="{{book}}">
  {{book}}
</option>
</select>


ไฟล์ bookauthor.html


<select>
<option ng-repeat="author in Author.bookauthor" value="{{author}}">
  {{author}}
</option>
</select>


ไฟล์ booktitle.html


<input type="text" placeholder="Search for book">
<input type="submit" value="search">


อธิบาย :
  • ไฟล์ booktype.html, bookauthor.html, booktitle.html เป็น HTML Template ที่สร้างแยกไว้เพื่อสะดวกในการเรียกใช้งาน

จากตัวอย่างด้านบน จะเห็นว่ามีการสร้าง Custom Directive ไว้ภายใน Module เดียว ซึ่งหากมีการสร้าง Directive อื่นๆ จำนวนมาก จะทำให้ยากต่อการจัดการ ดังนั้น จึงควรแยก Module สำหรับ book ออกมา เพื่อความสะดวกในการแก้ไขโค้ดภายหลัง โดยแก้ไขไฟล์ ดังนี้


ไฟล์ bookstore.html

<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="book-directive.js"></script>
</head>

อธิบาย :
  • เพิ่มส่วน include javascript จากไฟล์ book-directive.js

ไฟล์ app.js


(function(){
var app = angular.module('myapp',['book']);
})();


อธิบาย :
  • เพิ่ม dependency โดยอ้างอิงจากชื่อ module ของไฟล์ book-directive.js นั่นคือ ['book']
  • นำส่วนของการสร้าง Directive ไปใส่ในไฟล์ book-directive.js

สร้างไฟล์ book-directive.js


(function(){
var app = angular.module('book',[]);
app.directive('bookType',function(){
return{
restrict:'E',
templateUrl:'booktype.html',
controller:function(){
this.booktype = ['accounting','it','engineering'];
},
controllerAs:'Type'
};
});
app.directive('bookAuthor',function(){
return{
restrict:'E',
templateUrl:'bookauthor.html',
controller:function(){
this.bookauthor = ['Torben Lage Frandsen','Stephen Moffat','Steve Bark'];
},
controllerAs:'Author'
};
});
app.directive('bookTitle',function(){
return{
restrict:'E',
templateUrl:'booktitle.html'
};
});

}
)();


จะเห็นว่า book-directive.js เป็น module ที่ทำงานเกี่ยวกับ book ทั้งหมด ทำให้สะดวกในการแก้ไขโค้ดภายหลัง 

แม้จะเรียกใช้ Dependency ใน module แต่ยังคงต้อง include ไฟล์ javascript ของ module ที่ถูกอ้างอิงเสมอ โดย app.js เป็น Top-level module ที่ถูกเรียกใช้ผ่าน ng-app


AngularJS with Custom Directive

Custom Directive เป็นการสร้าง Element หรือ Attribute ด้วยตนเอง โดย Directive ที่สร้างจะเรียกใช้ HTML Template ที่สร้างแยกไว้ เพื่อลดการเขียนโค้ดเดิมซ้ำๆ ซึ่งคล้ายกับการใช้ ng-include ในบทความ AngularJS with ng-include

ประโยชน์ของ Custom Directive
  1. สามารถกำหนดให้นำ tag หรือ attribute จากไฟล์อื่นมาวางไว้ในตำแหน่งที่ต้องการได้
  2. สามารถสร้าง Controller ภายใน Directive ได้.
  3. สะดวกในการนำไปใช้ซ้ำ

ไฟล์ bookstore.html


<!DOCTYPE html><html ng-app="myapp">

<head>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>

<body> 

  <book-type></book-type>
</body>

</html>



อธิบาย :
  • <book-type> คือ element ที่สร้างจาก Custom Directive ในไฟล์ app.js
การตั้งชื่อ Element ใช้เครื่องหมาย "-" แยกระหว่างตัวพิมพ์ใหญ่/พิมพ์เล็ก ของชื่อ Directive เช่น 
Directive ชื่อ bookTitle ชื่อ Tag ต้องเป็น <book-title> เป็นต้น


ไฟล์ app.js


(function(){ 
  var app = angular.module('myapp',[]); 
  app.directive('bookType',function(){  
    return{  
      restrict:'E',  
templateUrl:'booktype.html'  
    };  
  }); 
app.controller('BookType',function(){
  this.booktype = ['accounting','it','engineering']; 
  });
})();


อธิบาย :
  • สร้าง module ชื่อ myapp
  • สร้าง directive ชื่อ bookType
  • directive ที่สร้างกำหนดเป็น Element (สามารถกำหนดเป็น Attribute ได้ด้วย เช่น restrict:'A')
  • เรียกใช้ template จากไฟล์ booktype.html
  • สร้าง controller ชื่อ BookType
  • ประกาศตัวแปร booktype ใน Controller มีชนิดข้อมูลเป็น Array

ไฟล์ booktype.html


<select ng-controller="BookType as Type"> 
  <option ng-repeat="book in Type.booktype" value="{{book}}">   
  {{book}} 
  </option>
</select>


อธิบาย :
  • เรียกใช้ controller Booktype ผ่าน ng-controller
  • ดึงข้อมูลจากตัวแปร Array ด้วย ng-repeat

จากตัวอย่างที่ผ่านมามีการสร้าง Controller แยกต่างหาก ตัวอย่างต่อไปจะเป็นการสร้าง Controller พร้อมกับการสร้าง Directive เพื่อเขียนโค้ดให้สั้นลง แก้ไขไฟล์ ดังนี้


ไฟล์ app.js


(function(){ 
  var app = angular.module('myapp',[]);
app.directive('bookType',function(){ 
return{  
restrict:'E',  
templateUrl:'booktype.html',  
      controller:function(){  
        this.booktype = ['accounting','it','engineering'];  
      },  
      controllerAs:'Type'  
    };  
  });
})();


อธิบาย :
  • กำหนด controller ให้ Directive โดยมีตัวแปร booktype เก็บข้อมูลแบบ Array
  • กำหนด Alias name ให้ controller ชื่อ Type (นำไปใช้ในการอ้างอิงกับไฟล์ Template)

ไฟล์ booktype.html


<select> 
  <option ng-repeat="book in Type.booktype" value="{{book}}">  
  {{book}} 
  </option>
</select>


อธิบาย :
  • นำส่วนที่เรียกใช้ Controller (ng-controller)  ออก เนื่องจาก template มีการสร้าง controller ใน Directive อยู่แล้ว
  • เรียกใช้ตัวแปรภายใน Controller ผ่าน Alias name ที่ชื่อ Type











วันพุธที่ 23 กันยายน พ.ศ. 2558

AngularJS with ng-include

บทความนี้อธิบายการ Reuse โค้ด HTML สำหรับหน้าเพจที่ต้องใช้โค้ดเดิมซ้ำๆ โดยการสร้าง Template HTML แยกต่างหาก เพื่อสะดวกต่อการเรียกใช้งาน


ไฟล์ bookstore.html


<html ng-app="">

<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
</head>

<body>
<h1>Book Type</h1>
<select>
<option value='accounting'>accounting</option>
<option value='it'>it</option>
<option value='engineering'>engineering</option>
</select>
</body>

</html>


โค้ดด้านบนเป็นการเขียนแบบปกติทั่วๆ ไป กรณี ที่ต้องการแสดง drop-down list ในหน้าอื่นๆ จะต้องเขียนโค้ดซ้ำๆ กัน ดังนั้น การใช้ ng-include จะช่วยลดระยะเวลาในการเขียนโค้ดได้ ดังนี้


ไฟล์ booktype.html


<h1>Book Type</h1>
<select>
<option value='accounting'>accounting</option>
<option value='it'>it</option>
<option value='engineering'>engineering</option>
</select>


ไฟล์ bookstore.html


<html ng-app="">

<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
</head>

<body>
<div ng-include="'booktype.html'"></div>
</body>

</html>

อธิบาย :

  • ไฟล์ booktype.html เป็น Template สำหรับเรียกใช้งานใน Element ต่างๆ
  • ng-include จะทำการดึงโค้ดจากไฟล์ booktype.html มาใส่ภายใน <div>..</div>