ฉันรู้ว่าตอนนี้คำถามนี้เก่าแล้ว แต่หลังจากทำการวิจัยมากมายเกี่ยวกับวิธีแก้ปัญหาต่างๆของปัญหานี้ฉันคิดว่าฉันอาจมีวิธีแก้ปัญหาที่ดีกว่านี้
อัปเดต 1:ตั้งแต่โพสต์คำตอบนี้ฉันได้เพิ่มโค้ดทั้งหมดนี้ลงในบริการง่ายๆที่ฉันโพสต์ไปยัง GitHub ซื้อคืนภาคตั้งอยู่ที่นี่ อย่าลังเลที่จะตรวจสอบสำหรับข้อมูลเพิ่มเติม
อัปเดต 2:คำตอบนี้ดีมากหากสิ่งที่คุณต้องการคือโซลูชันที่มีน้ำหนักเบาสำหรับการดึงสไตล์ชีตสำหรับเส้นทางของคุณ หากคุณต้องการโซลูชั่นที่สมบูรณ์มากขึ้นสำหรับการจัดการ stylesheets ตามความต้องการตลอดทั้งแอพลิเคชันของคุณคุณอาจต้องการที่จะชำระเงินโครงการ AngularCSS Door3 ของ มีฟังก์ชันการทำงานที่ละเอียดกว่ามาก
เผื่อว่าในอนาคตจะมีใครสนใจนี่คือสิ่งที่ฉันคิดขึ้นมา:
1. สร้างคำสั่งที่กำหนดเองสำหรับ<head>องค์ประกอบ:
app.directive('head', ['$rootScope','$compile',
function($rootScope, $compile){
return {
restrict: 'E',
link: function(scope, elem){
var html = '<link rel="stylesheet" ng-repeat="(routeCtrl, cssUrl) in routeStyles" ng-href="{{cssUrl}}" />';
elem.append($compile(html)(scope));
scope.routeStyles = {};
$rootScope.$on('$routeChangeStart', function (e, next, current) {
if(current && current.$$route && current.$$route.css){
if(!angular.isArray(current.$$route.css)){
current.$$route.css = [current.$$route.css];
}
angular.forEach(current.$$route.css, function(sheet){
delete scope.routeStyles[sheet];
});
}
if(next && next.$$route && next.$$route.css){
if(!angular.isArray(next.$$route.css)){
next.$$route.css = [next.$$route.css];
}
angular.forEach(next.$$route.css, function(sheet){
scope.routeStyles[sheet] = sheet;
});
}
});
}
};
}
]);
คำสั่งนี้ทำสิ่งต่อไปนี้:
- มันรวบรวม (ใช้
$compile) สตริง HTML ที่ใช้สร้างชุดของ<link />แท็กสำหรับทุกรายการในscope.routeStylesวัตถุที่ใช้และng-repeatng-href
- ต่อท้ายชุด
<link />องค์ประกอบที่คอมไพล์นั้นเข้ากับ<head>แท็ก
- จากนั้นใช้
$rootScopeเพื่อฟัง'$routeChangeStart'เหตุการณ์ สำหรับทุก'$routeChangeStart'เหตุการณ์จะจับ$$routeออบเจ็กต์"ปัจจุบัน" (เส้นทางที่ผู้ใช้กำลังจะออก) และลบไฟล์ css เฉพาะบางส่วนออกจาก<head>แท็ก นอกจากนี้ยังจับ$$routeออบเจ็กต์"next" (เส้นทางที่ผู้ใช้กำลังจะไป) และเพิ่มไฟล์ css เฉพาะบางส่วนลงใน<head>แท็ก
- และ
ng-repeatส่วนหนึ่งของ<link />แท็กที่คอมไพล์จะจัดการการเพิ่มและการลบสไตล์ชีตเฉพาะหน้าทั้งหมดตามสิ่งที่เพิ่มหรือลบออกจากscope.routeStylesออบเจ็กต์
หมายเหตุ: นี้ต้องการให้คุณng-appแอตทริบิวต์อยู่ใน<html>องค์ประกอบที่ไม่ได้อยู่ในหรือสิ่งที่อยู่ภายใน<body><html>
2. ระบุสไตล์ชีตที่เป็นของเส้นทางโดยใช้$routeProvider:
app.config(['$routeProvider', function($routeProvider){
$routeProvider
.when('/some/route/1', {
templateUrl: 'partials/partial1.html',
controller: 'Partial1Ctrl',
css: 'css/partial1.css'
})
.when('/some/route/2', {
templateUrl: 'partials/partial2.html',
controller: 'Partial2Ctrl'
})
.when('/some/route/3', {
templateUrl: 'partials/partial3.html',
controller: 'Partial3Ctrl',
css: ['css/partial3_1.css','css/partial3_2.css']
})
}]);
การกำหนดค่านี้เพิ่มcssคุณสมบัติที่กำหนดเองให้กับออบเจ็กต์ที่ใช้ในการตั้งค่าเส้นทางของแต่ละเพจ วัตถุที่ได้รับการส่งผ่านไปยังแต่ละเหตุการณ์เป็น'$routeChangeStart' .$$routeดังนั้นเมื่อฟัง'$routeChangeStart'เหตุการณ์เราสามารถคว้าcssคุณสมบัติที่เราระบุไว้และต่อท้าย / ลบ<link />แท็กเหล่านั้นได้ตามต้องการ โปรดทราบว่าการระบุcssคุณสมบัติบนเส้นทางเป็นทางเลือกโดยสมบูรณ์เนื่องจากถูกละเว้นจาก'/some/route/2'ตัวอย่าง หากเส้นทางนั้นไม่มีcssคุณสมบัติ<head>คำสั่งก็จะไม่ทำอะไรเลยสำหรับเส้นทางนั้น โปรดทราบว่าคุณยังสามารถมีสไตล์ชีตเฉพาะเพจได้หลายหน้าต่อเส้นทางดัง'/some/route/3'ตัวอย่างด้านบนโดยที่cssคุณสมบัติคืออาร์เรย์ของพา ธ สัมพัทธ์ไปยังสไตล์ชีทที่จำเป็นสำหรับเส้นทาง
3. คุณทำเสร็จแล้ว
สองสิ่งนี้ตั้งค่าทุกอย่างที่จำเป็นและในความคิดของฉันด้วยรหัสที่สะอาดที่สุดเท่าที่จะเป็นไปได้
หวังว่าจะช่วยคนอื่นที่อาจกำลังดิ้นรนกับปัญหานี้ได้มากเท่าที่ฉันเป็น
<link>แท็กcss ในรูปแบบนี้กับ Chrome ล่าสุดเซิร์ฟเวอร์บนเครื่องภายในของฉัน (และเปิด "ปิดการใช้งานแคช" เพื่อจำลองเงื่อนไข "โหลดครั้งแรก") ฉันคิดว่าการแทรก<style>แท็กล่วงหน้าใน html บางส่วนบนเซิร์ฟเวอร์จะหลีกเลี่ยงปัญหานี้ได้