使用 Bootstrap SB Admin 2 (Live Preview) 樣版 ,
整合 AngularJS 遇到了幾個關於 metisMenu (Live Demo) 的問題,
第一個問題是如果 menu 在 ng-include 裡面的話,
並不會正常運作,而是處於完全展開的情況。
原因是原本在 sb-admin-2.js 的程式碼:
$(function() {
$('#side-menu').metisMenu();
});
在第一次載入頁面時已執行完畢,
當 angular app 載入 ng-include 之後,並沒有做任何的動作。
解決辦法就是在 ng-include 加入 onload 函式,
在 controller 加入下列程式碼後解決:
$scope.loaded = function() {
$('#side-menu').metisMenu();
}
完整的 Plunker 範例
第二個問題是 metisMenu 的 active 功能沒有正常運作,
原因一樣是因為原本的設計是頁面載入完成後執行程式碼:
var url = window.location;
var element = $('ul.nav a').filter(function() {
return this.href == url;
}).addClass('active').parent().parent().addClass('in').parent();
if (element.is('li')) {
element.addClass('active');
}
然而使用 Angular 實作 Single Page Application 之後,
切換頁面並不會重新載入 js,所以沒有觸發這個動作。
解決辦法是當頁面改變後執行這個動作,如下列程式碼:
.run(['$rootScope', function ($rootScope) {
$rootScope.$on('$viewContentLoaded', function (event) {
$('ul.nav a').removeClass('active');
var url = window.location;
var element = $('ul.nav a').filter(function () {
return this.href == url || url.href.indexOf(this.href) == 0;
}).addClass('active').parent().parent().addClass('in').parent();
if (element.is('li')) {
element.addClass('active');
}
});
}]);
jquery metisMenu not working inside ng-include
http://stackoverflow.com/questions/26335696/jquery-metismenu-not-working-inside-ng-include
Finished Loading of ng-include in angular js
http://stackoverflow.com/questions/27576643/finished-loading-of-ng-include-in-angular-js
2016年9月18日 星期日
2016年7月19日 星期二
如何使用 Closure Compiler 最小化 JavaScript 產生 Source Maps 後進行偵錯
本文介紹以一個 AngularJS App 當範例,如何使用 Closure Compiler 最小化 (minimizes) 後產生的 Source Map 透過 Chrome 來進行偵錯 (Debug)。
Closure Compiler 是 Google 開發的 JavaScript 最小化編譯器,
關於細節可以參考 Google Closure Compiler 編譯器:產生最佳化(最小化)JavaScript 程式碼。
本文使用的範例是 Kuroneko Idle Game (雖然不能算是一個遊戲)
所有的程式碼在 GitHub
https://github.com/allyusd/kuroneko
範例網站
http://allyusd.github.io/kuroneko
首先看一下完整建置指令
java -jar compiler-latest\compiler.jar --js_output_file myapp.min.js --create_source_map myapp.min.js.map --output_wrapper "%%output%%//# sourceMappingURL=myapp.min.js.map" js/**.js
這一段指令,將 js 目錄下含子目錄的所有 js 檔案,都合併成 myapp.min.js,並且在最後加上 sourceMappingURL 相關文字,同時產生 myapp.min.js.map 這個 Source Map 檔案。
參數介紹
js_output_file 表示最小化後輸出的 js 檔案名稱
create_source_map 表示同時要產生 Source Map,並指定檔案名稱
output_wrapper 可以進行加工,這個例子是加上 #sourceMappingURL 關鍵字
先介紹一下最小化,在開發 AngularJS (或任何 JavaScript 應用) 時,大部份的情況像是下圖的結構。

透過 Closure Compiler 可以合併成單一檔案,減少 Http request 次數,減少空白或換行字元,用短變數的替換…等等的好處。但是衍生了一個問題,就是不方便偵錯,這是用 Chrome 看到最小化後的結果(部份)。

人是貪心的,有沒有辦法魚與熊掌兼得呢?
實際上是有的,就是利用 Source Map,只要加上 create_source_map 參數就能產生,但是要如何使用呢?
我們在最小化的檔案 myapp.min.js 加上 sourceMappingURL 告訴瀏覽器 Source Map 的位置,接著用 Chrome 查看會出現下圖。

眼尖的話會發現除了 myapp.min.js 外出現很多斜體字檔案,其實就是合併前的 js 檔。開心的別太早,點開檔案發現裡面是空白的,因為並沒有把原始檔案上傳,如果有上傳的話,這時候已經可以看到原本的 JavaScript 檔案內容。
因為不想上傳多餘的東西,所以我們要偵錯的話必須讓 Chrome 知道原本的檔案在哪裡,首先在空白處點擊 Add folder to workspace

指定本地檔案路徑後,Chrome 上方會出現授權請求及警語。

按下允許後下方會出現本地工作目錄。

接著剩下最後一個動作了,在上面斜體字檔案按下右鍵,選擇 Map to file system resource...

最後選擇對應的本地檔案就完成了,結果如下圖

這些原始檔可不是只能看看而已,可以下中斷點的偵錯的喔!

資料來源
Introduction to JavaScript Source Maps
http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/
Map Preprocessed Code to Source Code
Set Up Persistence with DevTools Workspaces
Closure Compiler 是 Google 開發的 JavaScript 最小化編譯器,
關於細節可以參考 Google Closure Compiler 編譯器:產生最佳化(最小化)JavaScript 程式碼。
本文使用的範例是 Kuroneko Idle Game (雖然不能算是一個遊戲)
所有的程式碼在 GitHub
https://github.com/allyusd/kuroneko
範例網站
http://allyusd.github.io/kuroneko
首先看一下完整建置指令
java -jar compiler-latest\compiler.jar --js_output_file myapp.min.js --create_source_map myapp.min.js.map --output_wrapper "%%output%%//# sourceMappingURL=myapp.min.js.map" js/**.js
這一段指令,將 js 目錄下含子目錄的所有 js 檔案,都合併成 myapp.min.js,並且在最後加上 sourceMappingURL 相關文字,同時產生 myapp.min.js.map 這個 Source Map 檔案。
參數介紹
js_output_file 表示最小化後輸出的 js 檔案名稱
create_source_map 表示同時要產生 Source Map,並指定檔案名稱
output_wrapper 可以進行加工,這個例子是加上 #sourceMappingURL 關鍵字
先介紹一下最小化,在開發 AngularJS (或任何 JavaScript 應用) 時,大部份的情況像是下圖的結構。

透過 Closure Compiler 可以合併成單一檔案,減少 Http request 次數,減少空白或換行字元,用短變數的替換…等等的好處。但是衍生了一個問題,就是不方便偵錯,這是用 Chrome 看到最小化後的結果(部份)。

人是貪心的,有沒有辦法魚與熊掌兼得呢?
實際上是有的,就是利用 Source Map,只要加上 create_source_map 參數就能產生,但是要如何使用呢?
我們在最小化的檔案 myapp.min.js 加上 sourceMappingURL 告訴瀏覽器 Source Map 的位置,接著用 Chrome 查看會出現下圖。

眼尖的話會發現除了 myapp.min.js 外出現很多斜體字檔案,其實就是合併前的 js 檔。開心的別太早,點開檔案發現裡面是空白的,因為並沒有把原始檔案上傳,如果有上傳的話,這時候已經可以看到原本的 JavaScript 檔案內容。
因為不想上傳多餘的東西,所以我們要偵錯的話必須讓 Chrome 知道原本的檔案在哪裡,首先在空白處點擊 Add folder to workspace

指定本地檔案路徑後,Chrome 上方會出現授權請求及警語。

按下允許後下方會出現本地工作目錄。

接著剩下最後一個動作了,在上面斜體字檔案按下右鍵,選擇 Map to file system resource...

最後選擇對應的本地檔案就完成了,結果如下圖

這些原始檔可不是只能看看而已,可以下中斷點的偵錯的喔!

資料來源
Introduction to JavaScript Source Maps
http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/
Map Preprocessed Code to Source Code
https://developers.google.com/web/tools/chrome-devtools/debug/readability/source-maps
Secrets of the Browser Developer Tools
http://devtoolsecrets.com/secret/debugging-use-javascript-source-maps.htmlSet Up Persistence with DevTools Workspaces
https://developers.google.com/web/tools/setup/setup-workflow
2014年5月7日 星期三
Write to file - Node.js
將文字新增在原本檔案之後,參考網路範例後改寫如下:
參考來源:
How to append to a file in Node?
http://stackoverflow.com/questions/3459476/how-to-append-to-a-file-in-node
var fs = require('fs');
// 宣告函式
var writelog = function(filepath, log){
fs.open(filepath, 'a', 666, function( e, id ) {
fs.write(id, log, null, 'utf8', function(){
fs.close(id, function(){
//console.log('file closed');
});
});
});
};
// 目錄要事先建好喔
var filepath = 'C:/Test/I-Love-You.txt'
var message = 'Hello Kitty!'
// 呼叫函式
writelog(filepath, message + '\r\n');
參考來源:
How to append to a file in Node?
http://stackoverflow.com/questions/3459476/how-to-append-to-a-file-in-node
2014年3月4日 星期二
WebSocket Server - Node.js
會有這一篇是想要試一下 HTML5 WebSocket 連線,本來是準備直接使用 www.websocket.org 的 Echo Test WebSocket Server,但是這個服務好像失效了,所以只好自己動手建立一個 WebSocket Server 嘍!
這次使用 Node.js 來建立一個 WebSocket Server,我們直接使用 ws 這個 Node.js 模組,ws 是一個 node.js 的 WebSocket 實作。
首先安裝好 Node.js,接著用 npm 安裝 ws 模組,然後使用這段程式碼:
上面是從官方範例小改一下的 echo server,將上面的程式碼存成 websocketserver.js 檔,然後在命令列輸入 node websocketserver.js 就可以啟動 WebSocketServer 嘍,很快速吧!
參考資料:
www.websocket.org
http://www.websocket.org/echo.html
ws: a node.js websocket implementation
http://einaros.github.io/ws/
這次使用 Node.js 來建立一個 WebSocket Server,我們直接使用 ws 這個 Node.js 模組,ws 是一個 node.js 的 WebSocket 實作。
首先安裝好 Node.js,接著用 npm 安裝 ws 模組,然後使用這段程式碼:
var WebSocketServer = require('ws').Server
, wss = new WebSocketServer({port: 8080});
wss.on('connection', function(ws) {
ws.on('message', function(message) {
console.log('received: %s', message);
ws.send(message);
});
});
上面是從官方範例小改一下的 echo server,將上面的程式碼存成 websocketserver.js 檔,然後在命令列輸入 node websocketserver.js 就可以啟動 WebSocketServer 嘍,很快速吧!
參考資料:
www.websocket.org
http://www.websocket.org/echo.html
ws: a node.js websocket implementation
http://einaros.github.io/ws/
訂閱:
文章 (Atom)