標籤:style blog http java color 使用
AngularJS是一款來自Google的前端JS架構,體積非常小,但是設計理念和功能卻非常強大。
教程
AngularJS中文社區
問題
在一款Web應用中,雖然我們儘可能的避免無節制地使用全域變數,但有時確實需要一些全域變數的存在已保證在所有頁面中都能處理某些事件。
在本文的例子中,該應用需要在安卓平台上接收手機簡訊並即時響應(此處先撇開具體的實現外掛程式,接收和傳送簡訊都用控制台來類比),為此我們定義了一個JavaScript的全域對象如下:
1 var native_accessor = { 2 //傳送簡訊函數 3 send_sms: function (phone, message) { 4 //通過控制台類比 5 console.log(phone, message); 6 //實際外掛程式調用 7 //native_access.send_sms({"receivers":[{"name":‘name‘, "phone":phone}]}, {"message_content":message}); 8 }, 9 10 //接收簡訊函數11 receive_message: function (json_message) {12 if (typeof this.process_received_message === ‘function‘) {13 this.process_received_message(json_message);14 }15 },16 17 //處理簡訊函數18 process_received_message: function (json_message) {19 Message.received_new_item(json_message);20 }21 }22 23 //接收簡訊時自動調用的函數24 function notify_message_received(message_json) {25 native_accessor.receive_message(message_json);26 }
上面的代碼中設立了一個Javascript的全域對象native_accessor和一個全域函數notify_message_received(message_json),其中native_accessor由三個不同功能函數組成。當系統接收到簡訊時,將會自動觸發notify_message_received(message_json)函數。
在本例中,有一個活動報名頁面,其中需要顯示所有已報名者的電話,收到有效報名簡訊後要自動對頁面進行更新。(當然,即便不在活動報名頁面還是依然要能夠接收簡訊的。)活動報名頁面的相關html代碼如下:
1 <div id="detail_scope">2 <ul class="list-group">3 <li class="list-group-item" ng-repeat="message in message_list | orderBy:‘-name‘">4 {{message.name}}5 <span class="pull-right">{{message.phone}}</span>6 </li>7 </ul>8 </div>
上面的代碼中,我們建立了一個顯示“姓名”和“號碼”的列表,姓名在左號碼在右。其中,為了能夠在外部存取這個AngularJS模板,我們在這個div中增加了一個id標籤,內容可以任意(在該控制器內的任意元素上使用該id標籤均可)。
接下來,由於在上面的代碼中我們在收到簡訊時調用了Message.received_new_item(json_message)這個方法,現在我們來考慮相關的實現代碼:
1 //這部分可以忽略,直接看Message.refresh_ui_list() 2 Message.received_new_item = function(message_json) { 3 var message_text = message_json.messages[0].message; 4 var message_phone = message_json.messages[0].phone; 5 var header_is_right = message_text.substring(0,2).toUpperCase() == ‘BM‘; 6 //檢查短格式信是不是為“BM”打頭 7 if(header_is_right) { 8 var message_name = message_text.substring(2).replace(‘ ‘, ‘‘); 9 //檢查當前的活動狀態是否允許報名10 var activity_status = localStorage.getItem("activity_status") || "prepare";11 if(activity_status == "prepare") {12 Message.sendback_info(message_phone, "early");13 }14 else if(activity_status == "over") {15 Message.sendback_info(message_phone, "late");16 }17 else {18 var message_list = Message.get_all_items();19 //檢查該人員是否重複報名20 if(!Message.check_if_repeat(message_phone)) {21 var activity_name = Activity.get_current_item();22 message_list.splice(0,0,{name:message_name, phone:message_phone, activity:activity_name});23 Message.save_all_items(message_list);24 //這裡才是調用的頁面重新整理函數25 Message.refresh_ui_list();26 Message.sendback_info(message_phone, "success");27 }28 } 29 }30 };31 32 33 //實現頁面自動重新整理的函數34 Message.refresh_ui_list = function () {35 //將頁面部分的scope提取出來作為變數36 var detail_scope = angular.element("#detail_scope").scope();37 //如果應用不在該頁面,該變數為undefined,繼續執行控制台會報錯(不過依然可以執行)38 if(detail_scope) {39 //需要特別注意的$apply方法40 detail_scope.$apply(function () {41 detail_scope.update_when_receive();42 });43 }44 };
在上面的代碼中,為了能夠在全域中調用對用controller的scope內的函數,我們通過angular.element("#element_id").scope()的方法從AngularJS中提取出該scope,此時可以把該scope看作一個的JavaScript對象。接著就可以使用調用對象函數的方法來調用scope內的函數了。
需要注意的是,直接調用該方法時,雖然對應的資料能夠發生更新,但是並不會直接影響頁面,不知道是不是非UI線程不能直接修改UI元素的道理。為此,我們需要通過調用$apply方法,而將所需函數作為該方法的參數,這樣就能實現頁面的同步更新了。
順便貼一下被調用的局部方法:
1 $scope.update_when_receive = function () {2 $scope.message_list = Message.read_all_items($scope.activity_name);3 if($scope.message_list.length != 0) {4 $scope.member_count = "(".concat($scope.message_list.length.toString()).concat("人)");5 }6 else {7 $scope.member_count = "";8 }9 };
這裡的方法中實現了更新列表和統計人數的功能,鑒於在本文中確實不重要,此處稍稍略過,完整帶項目代碼請見https://github.com/trotyl/party_bid
如對於本文中的任何內容有疑問或者想要提供一些意見或建議,都可以在下方評論或者私信聯絡~