ขอบคุณแหล่งข้อมูลที่มีค่าจำนวนมากฉันได้รับคำแนะนำทั่วไปสำหรับการใช้งานส่วนประกอบในแอป AngularJS:
ตัวควบคุม
ควบคุมควรจะเป็นเพียงinterlayerระหว่างรูปแบบและมุมมอง พยายามทำให้ผอมที่สุด
ขอแนะนำอย่างยิ่งให้หลีกเลี่ยงตรรกะทางธุรกิจในคอนโทรลเลอร์ ควรย้ายไปที่โมเดล
ควบคุมอาจสื่อสารกับตัวควบคุมอื่น ๆ โดยใช้วิธีการภาวนา (เป็นไปได้เมื่อเด็กต้องการที่จะสื่อสารกับผู้ปกครอง) หรือ$ Emit , $ ออกอากาศและ$ เกี่ยวกับวิธีการ ข้อความที่ปล่อยออกมาและออกอากาศควรถูกเก็บไว้ให้น้อยที่สุด
คอนโทรลเลอร์ไม่ควรสนใจเกี่ยวกับการนำเสนอหรือการจัดการ DOM
พยายามที่จะหลีกเลี่ยงการควบคุมที่ซ้อนกัน ในกรณีนี้ตัวควบคุมหลักถูกตีความเป็นแบบจำลอง ฉีดโมเดลเป็นบริการสาธารณะแทน
ขอบเขตในคอนโทรลเลอร์ควรใช้สำหรับการรวมโมเดลด้วยมุมมองและการ
ห่อหุ้มโมเดลมุมมองเป็นรูปแบบการออกแบบการนำเสนอโมเดล
ขอบเขต
ขอบเขตการรักษาเป็นแบบอ่านอย่างเดียวในแม่แบบและการเขียนเฉพาะในตัวควบคุม วัตถุประสงค์ของขอบเขตคือเพื่ออ้างอิงถึงโมเดลไม่ใช่โมเดล
เมื่อทำการรวมสองทิศทาง (โมเดล ng) ตรวจสอบให้แน่ใจว่าคุณไม่ได้ผูกกับคุณสมบัติขอบเขตโดยตรง
แบบ
รุ่นใน AngularJS เป็นซิงเกิลที่กำหนดโดยบริการ
รุ่นมีวิธีที่ยอดเยี่ยมในการแยกข้อมูลและการแสดงผล
รุ่นเป็นผู้ที่สำคัญสำหรับการทดสอบหน่วยเช่นที่พวกเขามักจะมีอีกหนึ่งการพึ่งพา (รูปแบบของอีซีแอเหตุการณ์บางอย่างในกรณีที่พบบ่อย$ rootScope ) และมีทดสอบสูงตรรกะโดเมน
แบบจำลองควรได้รับการพิจารณาว่าเป็นการใช้งานของหน่วยงานเฉพาะ มันขึ้นอยู่กับความรับผิดชอบหลักเดียว หน่วยเป็นตัวอย่างที่เป็นผู้รับผิดชอบในขอบเขตของตัวเองของตรรกะที่เกี่ยวข้องที่อาจจะเป็นองค์กรเดียวในโลกจริงและอธิบายในการเขียนโปรแกรมระดับโลกในแง่ของข้อมูลและรัฐ
โมเดลควรสรุปข้อมูลแอปพลิเคชันของคุณและจัดเตรียมAPI
เพื่อเข้าถึงและจัดการข้อมูลนั้น
รุ่นควรเป็นแบบพกพาจึงสามารถเคลื่อนย้ายไปยังแอปพลิเคชันที่คล้ายกันได้อย่างง่ายดาย
ด้วยการแยกหน่วยของลอจิกในแบบจำลองของคุณคุณจะสามารถค้นหาอัปเดตและดูแลรักษาได้ง่ายขึ้น
รุ่นสามารถใช้วิธีการของแบบจำลองทั่วไปทั่วโลกที่ใช้กันทั่วไปสำหรับแอปพลิเคชันทั้งหมด
พยายามหลีกเลี่ยงการองค์ประกอบของรุ่นอื่น ๆ ในรูปแบบของคุณโดยใช้ฉีดพึ่งพาถ้ามันไม่ได้ขึ้นอยู่จริงๆที่จะลดส่วนประกอบการมีเพศสัมพันธ์และเพิ่มหน่วยตรวจสอบได้และการใช้งาน
พยายามหลีกเลี่ยงการใช้ฟังเหตุการณ์ในแบบจำลอง มันทำให้ยากต่อการทดสอบและฆ่าแบบจำลองในแง่ของความรับผิดชอบหลักเดียว
การนำโมเดลไปใช้
ในฐานะที่เป็นแบบจำลองควรสรุปเหตุผลในแง่ของข้อมูลและรัฐมันควร จำกัด การเข้าถึงสมาชิกของสถาปัตยกรรมดังนั้นเราจึงสามารถรับประกันการมีเพศสัมพันธ์หลวม
วิธีที่จะทำในแอปพลิเคชัน AngularJS คือการกำหนดโดยใช้ประเภทบริการจากโรงงาน สิ่งนี้จะช่วยให้เราสามารถกำหนดคุณสมบัติและวิธีการส่วนตัวได้อย่างง่ายดายและกลับสู่สาธารณะที่เข้าถึงได้ในที่เดียวซึ่งจะทำให้ผู้อ่านสามารถอ่านได้
ตัวอย่าง :
angular.module('search')
.factory( 'searchModel', ['searchResource', function (searchResource) {
var itemsPerPage = 10,
currentPage = 1,
totalPages = 0,
allLoaded = false,
searchQuery;
function init(params) {
itemsPerPage = params.itemsPerPage || itemsPerPage;
searchQuery = params.substring || searchQuery;
}
function findItems(page, queryParams) {
searchQuery = queryParams.substring || searchQuery;
return searchResource.fetch(searchQuery, page, itemsPerPage).then( function (results) {
totalPages = results.totalPages;
currentPage = results.currentPage;
allLoaded = totalPages <= currentPage;
return results.list
});
}
function findNext() {
return findItems(currentPage + 1);
}
function isAllLoaded() {
return allLoaded;
}
// return public model API
return {
/**
* @param {Object} params
*/
init: init,
/**
* @param {Number} page
* @param {Object} queryParams
* @return {Object} promise
*/
find: findItems,
/**
* @return {Boolean}
*/
allLoaded: isAllLoaded,
/**
* @return {Object} promise
*/
findNext: findNext
};
});
การสร้างอินสแตนซ์ใหม่
พยายามหลีกเลี่ยงการมีโรงงานที่ส่งคืนฟังก์ชันที่มีความสามารถใหม่เนื่องจากการเริ่มต้นการแบ่งการฉีดที่พึ่งพาและไลบรารีจะทำงานอย่างเชื่องช้าโดยเฉพาะสำหรับบุคคลที่สาม
วิธีที่ดีกว่าในการทำสิ่งเดียวกันให้สำเร็จคือใช้โรงงานเป็น API เพื่อส่งคืนคอลเลกชันของวัตถุด้วยวิธี getter และ setter ที่แนบมาด้วย
angular.module('car')
.factory( 'carModel', ['carResource', function (carResource) {
function Car(data) {
angular.extend(this, data);
}
Car.prototype = {
save: function () {
// TODO: strip irrelevant fields
var carData = //...
return carResource.save(carData);
}
};
function getCarById ( id ) {
return carResource.getById(id).then(function (data) {
return new Car(data);
});
}
// the public API
return {
// ...
findById: getCarById
// ...
};
});
โมเดลระดับโลก
โดยทั่วไปแล้วพยายามหลีกเลี่ยงสถานการณ์เช่นนี้และออกแบบโมเดลของคุณอย่างเหมาะสมดังนั้นจึงสามารถแทรกเข้าไปในตัวควบคุมและใช้ในมุมมองของคุณ
ในบางกรณีวิธีการบางอย่างจำเป็นต้องมีการเข้าถึงทั่วโลกภายในแอปพลิเคชัน เพื่อให้เป็นไปได้คุณสามารถกำหนดคุณสมบัติ ' common ' ใน$ rootScopeและผูกเข้ากับcommonModelระหว่างการบูทแอปพลิเคชัน:
angular.module('app', ['app.common'])
.config(...)
.run(['$rootScope', 'commonModel', function ($rootScope, commonModel) {
$rootScope.common = 'commonModel';
}]);
วิธีการทั่วโลกทั้งหมดของคุณจะอาศัยอยู่ในพื้นที่ ' ทั่วไป ' นี้เป็นชนิดของบางnamespace
แต่ไม่ได้กำหนดวิธีการใด ๆ โดยตรงใน$ rootScope ของคุณ สิ่งนี้สามารถนำไปสู่พฤติกรรมที่ไม่คาดคิดเมื่อใช้กับคำสั่ง ngModel ภายในขอบเขตมุมมองของคุณซึ่งโดยทั่วไปแล้วจะทำให้การกำหนดขอบเขตและนำไปสู่วิธีการในการแก้ไขปัญหา
ทรัพยากร
ทรัพยากรช่วยให้คุณโต้ตอบกับที่แตกต่างกันแหล่งข้อมูล
ควรจะดำเนินการโดยใช้เดียวรับผิดชอบหลักการ
โดยเฉพาะอย่างยิ่งมันเป็นพร็อกซีที่นำกลับมาใช้ใหม่เพื่อจุดสิ้นสุด HTTP / JSON
ทรัพยากรจะถูกฉีดในรูปแบบและให้โอกาสในการส่ง / ดึงข้อมูล
การใช้ทรัพยากร
โรงงานซึ่งสร้างวัตถุทรัพยากรที่ให้คุณโต้ตอบกับแหล่งข้อมูลฝั่งเซิร์ฟเวอร์ที่สงบ
วัตถุทรัพยากรที่ส่งคืนมีวิธีการดำเนินการที่ให้พฤติกรรมระดับสูงโดยไม่จำเป็นต้องโต้ตอบกับบริการ $ http ระดับต่ำ
บริการ
ทั้งรูปแบบและทรัพยากรที่มีให้บริการ
บริการนั้นไม่ได้มีการเชื่อมโยงกันและมีการใช้งานร่วมกันอย่างหลวม ๆ
บริการเป็นคุณสมบัติที่ Angular นำเสนอให้กับเว็บแอปฝั่งไคลเอ็นต์จากฝั่งเซิร์ฟเวอร์ซึ่งเป็นบริการที่ใช้กันมานาน
บริการในแอพเชิงมุมเป็นวัตถุทดแทนที่เชื่อมต่อกันโดยใช้การฉีดพึ่งพา
เชิงมุมมาพร้อมกับบริการประเภทต่างๆ แต่ละคนมีกรณีการใช้งานของตัวเอง โปรดอ่านการทำความเข้าใจประเภทบริการสำหรับรายละเอียด
ลองพิจารณาหลักการสำคัญของสถาปัตยกรรมบริการในแอปพลิเคชันของคุณ
โดยทั่วไปตามอภิธานศัพท์บริการเว็บ :
บริการเป็นทรัพยากรนามธรรมที่แสดงถึงความสามารถในการปฏิบัติงานที่ก่อให้เกิดการทำงานที่สอดคล้องกันจากมุมมองของหน่วยงานผู้ให้บริการและหน่วยงานที่ร้องขอ หากต้องการใช้งานจะต้องรับบริการจากตัวแทนผู้ให้บริการที่เป็นรูปธรรม
โครงสร้างฝั่งไคลเอ็นต์
ในด้านลูกค้าทั่วไปของแอพลิเคชันที่มีการแบ่งตัวออกเป็นโมดูล แต่ละโมดูลควรทดสอบได้เป็นหน่วยเดียว
พยายามกำหนดโมดูลขึ้นอยู่กับคุณสมบัติ / ฟังก์ชั่นหรือมุมมองไม่ใช่ตามประเภท ดูการนำเสนอของ Miskoสำหรับรายละเอียด
ส่วนประกอบโมดูลอาจถูกจัดกลุ่มตามอัตภาพตามประเภทเช่นตัวควบคุมรุ่นมุมมองตัวกรองคำสั่ง ฯลฯ
แต่โมดูลตัวเองยังคงนำมาใช้ใหม่ , โอนเปลี่ยนมือได้และทดสอบ
นอกจากนี้ยังง่ายสำหรับนักพัฒนาในการค้นหาบางส่วนของรหัสและการอ้างอิงทั้งหมด
โปรดดูที่องค์การรหัสใน AngularJS ขนาดใหญ่และการประยุกต์ใช้งานจาวาสคริปต์เพื่อดูรายละเอียด
ตัวอย่างของโครงสร้างโฟลเดอร์ :
|-- src/
| |-- app/
| | |-- app.js
| | |-- home/
| | | |-- home.js
| | | |-- homeCtrl.js
| | | |-- home.spec.js
| | | |-- home.tpl.html
| | | |-- home.less
| | |-- user/
| | | |-- user.js
| | | |-- userCtrl.js
| | | |-- userModel.js
| | | |-- userResource.js
| | | |-- user.spec.js
| | | |-- user.tpl.html
| | | |-- user.less
| | | |-- create/
| | | | |-- create.js
| | | | |-- createCtrl.js
| | | | |-- create.tpl.html
| |-- common/
| | |-- authentication/
| | | |-- authentication.js
| | | |-- authenticationModel.js
| | | |-- authenticationService.js
| |-- assets/
| | |-- images/
| | | |-- logo.png
| | | |-- user/
| | | | |-- user-icon.png
| | | | |-- user-default-avatar.png
| |-- index.html
ตัวอย่างที่ดีของการสร้างแอปพลิเคชันเชิงมุมจะดำเนินการโดยangular-app - https://github.com/angular-app/angular-app/tree/master/client/src
นี่คือการพิจารณาโดยผู้สร้างแอปพลิเคชันที่ทันสมัย - https://github.com/yeoman/generator-angular/issues/109