使用Angular.js開發的注意事項
前言
近期一直在玩Angularjs,不得不說,相對於Knockout,Angularjs這一MVVM框架更強大,也更複雜,各種教程網上到處都是,不過真正用到項目的時候會遇到各種坑。
一、ng-repeat
ng-repeat 用來識別某個elem 需要重複輸出,同時重複輸出的內容需為唯一
<div ng-app="app" ng-controller="control"> <h3 ng-repeat="content in repeatContent">ng-repeat: {{ content }}</h3> </div>
let app = angular.module("app", []); app.controller("control", ($scope) => { // 输出李滨泓 $scope.repeatContent = ["李", "滨", "泓"]; // 下面存在两个“泓”,会报错 // $scope.repeatContent = ["李", "滨", "泓", "泓"]; })
的關係
factory
factory 很像service,不同之處在於,service 在Angular 中是一個單例對象,即當需要使用service 時,使用new 關鍵字來建立一個(也僅此一個)service。而 factory 則是一個普通的函數,當需要用時,他也只是一個普通函數的調用方式,它可以返回各種形式的數據,例如通過返回一個功能函數的集合對象來將供與使用。
定義:
let app = angular.module("app", []); // 这里可以注入 $http 等 Provider app.factory("Today", () => { let date = new Date(); return { year: date.getFullYear(), month: date.getMonth() + 1, day: date.getDate() }; });
使用注入:
app.controller("control", (Today) => { console.log(Today.year); console.log(Today.month); console.log(Today.day); });
service
service因為它使用new 關鍵字新建,同時它可以用在controller 之間的通訊與資料交互,因為controller 在無用時其作用域鏈會被銷毀(例如使用路由跳到另一個頁面,同時使用了另一個controller)定義:let app = angular.module("app", []); // 这里可以注入 $http 等 Provider // 注意这里不可以使用 arrow function // arrow function 不能作为 constructor app.service("Today", function() { let date = new Date(); this.year = date.getFullYear(); this.month = date.getMonth() + 1; this.day = date.getDate(); });
app.controller("control", (Today) => { console.log(Today.year); console.log(Today.month); console.log(Today.day); });
provider 前對provider 進行一些參數的配置。
定義:
let app = angular.module("app", []); // 这里可以注入 $http 等 Provider // 注意这里不可以使用 arrow function // arrow function 不能作为 constructor app.provider("Today", function() { this.date = new Date(); let self = this; this.setDate = (year, month, day) => { this.date = new Date(year, month - 1, day); } this.$get = () => { return { year: this.date.getFullYear(), month: this.date.getMonth() + 1, day: this.date.getDate() }; }; });
使用注入:
// 这里重新配置了今天的日期是 2015年2月15日 // 注意这里注入的是 TodayProvider,使用驼峰命名来注入正确的需要配置的 provider app.config((TodayProvider) => { TodayProvider.setDate(2015, 2, 15); }); app.controller("control", (Today) => { console.log(Today.year); console.log(Today.month); console.log(Today.day); });
、handlebarbar ,而其中使用了handlebars 作為模板引擎,當node.js 對某URL 進行對應並render,由於其模板使用{ {} } 作為變數解析符號。同樣地,angular 也使用{ {} } 作為變數解析符號,所以當node.js 進行render 頁面後,如果{ {} } 內的變數不存在,則該個區域會被清空,而我的原意是這個作為angular 的解析所用,而不是handlebars 使用,同時我也想繼續使用handlebars,那麼此時就需要將angular 預設的{ {} } 解析符號重新定義。即使以依賴注入$interpolateProvider 進行定義,如下範例:
app.config($interpolateProvider => { $interpolateProvider.startSymbol('{[{'); $interpolateProvider.endSymbol('}]}'); });
ng-annotate-loader 應用於webpack +ular 在開發場景JS 壓縮後導致依賴注入失效並出現錯誤的解決方法
安裝
$ npm install ng-annotate-loader --save-dev
// webpack.config.js { test: /\.js?$/, exclude: /(node_modules|bower_components)/, loader: 'ng-annotate!babel?presets=es2015' },
,$scope 裡的資料改變並不會引起$digest 的dirty-checking 循環,這將導致當model 改變時,view 不會同步更新,這時我們需要自己主動觸發更新
HTML
<div>{{ foo }}</div> <button id="addBtn">go</button>
JavaScript
app.controller("control", ($scope) => { $scope.foo = 0; document.getElementById("addBtn").addEventListener("click", () => { $scope.foo++; }, false); })
很明顯,示例的意圖是當點擊button 時,foo 自增長並更新View,但是實際上,$scope.foo 是改變了,但是View 並不會刷新,這是因為foo 並沒有一個$watch 檢測變化後$apply,最終引起$digest,所以我們需要自己觸發$apply 或創建一個$watch 來觸發或檢測數據變化
JavaScript(使用$apply)
app.controller("control", ($scope) => { $scope.foo = 0; document.getElementById("addBtn").addEventListener("click", () => { $scope.$apply(function() { $scope.foo++; }); }, false); })
JavaScript(使用$watch & $digest)
app.controller("control", ($scope) => { $scope.foo = 0; $scope.flag = 0; $scope.$watch("flag", (newValue, oldValue) => { // 当 $digest 循环检测 flag 时,如果新旧值不一致将调用该函数 $scope.foo = $scope.flag; }); document.getElementById("addBtn").addEventListener("click", () => { $scope.flag++; // 主动触发 $digest 循环 $scope.$digest(); }, false); })
listener 將在當前watchExpression 回傳值和上次的watchExpression 回傳值不一致時被呼叫(使用!== 來嚴格地判斷不一致性,而不是使用== 來判斷,不過objectEquality == true 除外)
objectEquality 為boolean 值,當為true 時,將使用angular.equals 來判斷一致性,並使用angular.copy 來保存此次的Object 拷貝副本供給下一次的比較,這意味著複雜的對象檢測將會有效能和記憶體上的問題
七、$apply([exp])
function $apply(expr) { try { return $eval(expr); } catch (e) { $exceptionHandler(e); } finally { $root.$digest(); } }
如果在執行過程中跑出exception,那麼執行$exceptionHandler(e)
最後無論結果,都會執行一次 $digest 循環

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

這篇文章帶大家繼續angular的學習,簡單了解一下Angular中的獨立組件(Standalone Component),希望對大家有幫助!

這篇文章帶大家了解Angular中的獨立元件,看看怎麼在Angular中建立一個獨立元件,怎麼在獨立元件中導入已有的模組,希望對大家有幫助!

Angular專案過大,怎麼合理拆分它?以下這篇文章跟大家介紹一下合理分割Angular專案的方法,希望對大家有幫助!

NgModule 模組是Angular種一個重要的點,因為Angular的基本構造塊就是NgModule。這篇文章就來帶大家了解Angular中的NgModule模組,希望對大家有幫助!

這篇文章帶大家了解一下依賴注入,介紹一下依賴注入解決的問題和它原生的寫法是什麼,並聊聊Angular的依賴注入框架,希望對大家有所幫助!

怎麼自訂angular-datetime-picker格式?以下這篇文章聊聊自訂格式的方法,希望對大家有幫助!

這篇文章帶大家了解如何使用IDEA開發Angular,簡單介紹一下JetBrains IDEA中新建專案、運行專案的方法,希望對大家有幫助!
