ฉันรู้ว่าตอนนี้คำถามนี้เก่าแล้ว แต่หลังจากทำการวิจัยมากมายเกี่ยวกับวิธีแก้ปัญหาต่างๆของปัญหานี้ฉันคิดว่าฉันอาจมีวิธีแก้ปัญหาที่ดีกว่านี้
อัปเดต 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-repeat
ng-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 บางส่วนบนเซิร์ฟเวอร์จะหลีกเลี่ยงปัญหานี้ได้