寫ng應用時,往往需要封裝大量的指令。對於一些指令來說,可能是別的外掛程式改過來的,這時候就會要引入那些相關js。這個一個非常簡單的應用。實現起來也比較簡單。
虛擬碼如下:(以依賴於echarts和ckeditor為例)
<div ckeditor></div>
<div echarts></div>
<script src="jquery.js"></script>
<script src="ckeditor.js"></script>
<script src="echarts.js"></script>
<script src="angular.js"></script>
<script>
var app = angular.module('app', []);
app.directive('ckeditor', function(){...});
app.directive('echarts', function(){...});
.....
</script>
這看起來確實很ok。也確實能成功運行。
但在一個以項目中應用,這真的好嗎?
我個人覺得這個不好,主要在於如下:
當我這個頁面不需要ckeditor這個東西的時候了,即我要刪除這行代碼的時候
<div ckeditor></div>
此時我還要手動的刪除
<script src="ckeditor.js"></script>
不然會造成垃圾。因為我都用不到這個了啊。
還有一個問題是我一個後台有幾十個頁面,十幾個頁面中都要用ckeditor的。我不是要寫很多次
<script src="ckeditor.js"></script>
你TM這不是廢話。但在大項目中反覆維護這個有點複雜。有沒有更好的辦法。。。
我覺得些問題的根本在於實際是因為沒有解決要用到這個指令的時候再去載入相關js,此時,我們需要設計一個,按這個指令的時候再去載入相關js的方式。以echarts為例:
directivesApp.directive('bdzEcharts', function(){
return {
restrict: 'EA',
template: '<div></div>',
replace: true,
scope: {
option: '=?'
},
link: function(scope, element, attrs){
scope.$watch('option', function(){
var getChart = function () {
var myChart = echarts.init(element[0]);
myChart.setOption(scope.option);
};
if(!window.echarts){
$.getScript('/assets/vendor/echarts/2.0.3/build/echarts-plain.js', function(){
getChart();
});
}else{
getChart();
}
})
}
}
});
重要的代碼其實也就這麼幾句:
if(!window.echarts){
$.getScript('/assets/vendor/echarts/2.0.3/build/echarts-plain.js', function(){
getChart();
});
}else{
getChart();
}
動態去載入他相關的js。那麼判斷這個window.echarts又是做什麼的呢?
是因為有時候,我們一個頁面用到了幾次這個指令,其實這個js已經載入了,總沒必要反覆載入吧。所以才有這句。
最後再說幾句。因為$.getScript是非同步。所以其實這個js在載入時也可能出現判斷window.echarts實際沒有。最好的方式,如果你想完全判斷window.echarts是否存在 ,可以改為同步載入。
if(!window.echarts){
$.ajax({
async: false,
url: "/assets/vendor/echarts/2.0.3/build/echarts-plain.js",
dataType: "script",
success: function(){
getChart();
}
});
}else{
getChart();
}
這樣就能完美解決按需載入了。
現在你想想,你在一個頁面中添加一個指令,或者刪除一個指令的時候,你就不需要手動增加刪除一些js,爽吧