如何衡量一個人的 AngularJS 水平?
謝謝。怎麼能比較量化的評估一個人的angularjs(1.x)水平呢?
這個問題邀請我回答就對了。我提供一些面試時候問過的問題:
1. angular的數據綁定採用什麼機制?詳述原理
2. 兩個平級界面塊a和b,如果a中觸發一個事件,有哪些方式能讓b知道,詳述原理3. 一個angular應用應當如何良好地分層?4. angular應用常用哪些路由庫,各自的區別是什麼?
5. 如果通過angular的directive規劃一套全組件化體系,可能遇到哪些挑戰?6. 分屬不同團隊進行開發的angular應用,如果要做整合,可能會遇到哪些問題,如何解決?7. angular的缺點有哪些?8. 如何看待angular 1.2中引入的controller as 語法?9. 詳述angular的「依賴注入」10. 如何看待angular 2……上面是需要長篇大論的問題,再來一些小問題:
1. ng-if跟ng-show/hide的區別有哪些?
2. ng-repeat迭代數組的時候,如果數組中有相同值,會有什麼問題,如何解決?3. ng-click中寫的表達式,能使用JS原生對象上的方法,比如Math.max之類的嗎?為什麼?
4. {{now | "yyyy-MM-dd"}}這種表達式裡面,豎線和後面的參數通過什麼方式可以自定義?5. factory和service,provider是什麼關係?能全部答出來的人,應該大家都能認識了……強答一下。從小問題開始:1. ng-if跟ng-show/hide的區別有哪些?
第一點區別是,ng-if 在後面表達式為 true 的時候才創建這個 dom 節點,ng-show 是初始時就創建了,用 display:block 和 display:none 來控制顯示和不顯示。
第二點區別是,ng-if 會(隱式地)產生新作用域,ng-switch 、 ng-include 等會動態創建一塊界面的也是如此。
2. ng-repeat迭代數組的時候,如果數組中有相同值,會有什麼問題,如何解決?
會提示 Duplicates in a repeater are not allowed. 加 track by $index 可解決。當然,也可以 trace by 任何一個普通的值,只要能唯一性標識數組中的每一項即可(建立 dom 和數據之間的關聯)。
3. ng-click中寫的表達式,能使用JS原生對象上的方法,比如Math.max之類的嗎?為什麼?
不可以。只要是在頁面中,就不能直接調用原生的 JS 方法,因為這些並不存在於與頁面對應的 Controller 的 $scope 中。除非在 $scope 中添加了這個函數:
$scope.parseInt = function(x){
return parseInt(x);
}
4. {{now | "yyyy-MM-dd"}}這種表達式裡面,豎線和後面的參數通過什麼方式可以自定義?
定義方式:
app.filter("過濾器名稱",function(){
return function(需要過濾的對象, 過濾器參數1, 過濾器參數2, ...){
//...做一些事情
return 處理後的對象;
}
});
{{now | date : "yyyy-MM-dd"}}&&
// $filter("過濾器名稱")(需要過濾的對象, 參數1, 參數2,...)
$filter("date")(now, "yyyy-MM-dd hh:mm:ss");
&
click 時會產生一次更新的操作(至少觸發兩次 $digest 循環)
- 按下按鈕
- 瀏覽器接收到一個事件,進入到 angular context
- $digest 循環開始執行,查詢每個 $watch 是否變化
- 由於監視 $scope.val 的 $watch 報告了變化,因此強制再執行一次 $digest 循環
- 新的 $digest 循環未檢測到變化
- 瀏覽器拿回控制器,更新 $scope.val 新值對應的 dom
$digest 循環的上限是 10 次(超過 10次後拋出一個異常,防止無限循環)。
2. 兩個平級界面塊a和b,如果a中觸發一個事件,有哪些方式能讓b知道,詳述原理
這個問題換一種說法就是,如何在平級界面模塊間進行通信。有兩種方法,一種是共用服務,一種是基於事件。
a. 共用服務
在 Angular 中,通過 factory 可以生成一個單例對象,在需要通信的模塊 a 和 b 中注入這個對象即可。
b. 基於事件
這個又分兩種方式
第一種是藉助父 controller。在子 controller 中向父 controller 觸發($emit)一個事件,然後在父 controller 中監聽($on)事件,再廣播($broadcast)給子 controller ,這樣通過事件攜帶的參數,實現了數據經過父 controller,在同級 controller 之間傳播。
第二種是藉助 $rootScope。每個 Angular 應用默認有一個根作用域 $rootScope, 根作用域位於最頂層,從它往下掛著各級作用域。所以,如果子控制器直接使用 $rootScope 廣播和接收事件,那麼就可實現同級之間的通信。
3. 一個angular應用應當如何良好地分層?
分兩個方面講
a. 目錄結構的劃分
對於小型項目,可以按照文件類型組織,比如
css
js
controllers
models
services
filters
templates
但是對於規模較大的項目,最好按業務模塊劃分,比如
css
modules
account
controllers
models
services
filters
templates
disk
controllers
models
services
filters
templates
modules 下最好再有一個 common 目錄來存放公共的東西。
b. 邏輯代碼的劃分
作為一個 MVVM 框架,Angular 應用本身就應該按照 模型,視圖模型(控制器),視圖來劃分。
這裡邏輯代碼的拆分,主要是指盡量讓 controller 這一層很薄。提取共用的邏輯到 service 中 (比如後台數據的請求,數據的共享和緩存,基於事件的模塊間通信等),提取共用的界面操作到 directive 中(比如將日期選擇、分頁等封裝成組件等),提取共用的格式化操作到 filter 中等等。
在複雜的應用中,也可以為實體建立對應的構造函數,比如硬碟(Disk)模塊,可能有列表、新建、詳情這樣幾個視圖,並分別對應的有 controller,那麼可以建一個 Disk 構造函數,裡面完成數據的增刪改查和驗證操作,有跟 Disk 相關的 controller,就注入 Disk 構造器並生成一個實例,這個實例就具備了增刪改查和驗證方法。這樣既層次分明,又實現了復用(讓 controller 層更薄了)。
4. angular應用常用哪些路由庫,各自的區別是什麼?
Angular1.x 中常用 ngRoute 和 ui.router,還有一種為 Angular2 設計的 new router(面向組件)。後面那個沒在實際項目中用過,就不講了。
無論是 ngRoute 還是 ui.router,作為框架額外的附加功能,都必須以 模塊依賴 的形式被引入。
兩者區別是:
ngRoute 模塊是 Angular 自帶的路由模塊,而 ui.router 模塊是基於 ngRoute模塊開發的第三方模塊。
ui.router 是基於 state (狀態)的, ngRoute 是基於 url 的,ui.router模塊具有更強大的功能,主要體現在視圖的嵌套方面。
使用 ui.router 能夠定義有明確父子關係的路由,並通過 ui-view 指令將子路由模版插入到父路由模板的 &&
5. 如果通過angular的directive規劃一套全組件化體系,可能遇到哪些挑戰?
沒有自己用 directive 做過一全套組件,講不出。
能想到的一點是,組件如何與外界進行數據的交互,以及如何通過簡單的配置就能使用吧。
6. 分屬不同團隊進行開發的angular應用,如果要做整合,可能會遇到哪些問題,如何解決?
可能會遇到不同模塊之間的衝突。比如一個團隊所有的開發在 moduleA 下進行,另一團隊開發的代碼在 moduleB 下:
angular.module("myApp.moduleA", [])
.factory("serviceA", function(){
...
})
angular.module("myApp.moduleB", [])
.factory("serviceA", function(){
...
})
angular.module("myApp", ["myApp.moduleA", "myApp.moduleB"])
會導致兩個 module 下面的 serviceA 發生了覆蓋。
貌似在 Angular1.x 中並沒有很好的解決辦法,所以最好在前期進行統一規劃,做好約定,嚴格按照約定開發,每個開發人員只寫特定區塊代碼。
7. angular的缺點有哪些?
a. 強約束
導致學習成本較高,對前端不友好。
但遵守 AngularJS 的約定時,生產力會很高,對 Java 程序員友好。
b. 不利於 SEO
因為所有內容都是動態獲取並渲染生成的,搜索引擎沒法爬取。
一種解決辦法是,對於正常用戶的訪問,伺服器響應 AngularJS 應用的內容;對於搜索引擎的訪問,則響應專門針對 SEO 的HTML頁面。
c. 性能問題
作為 MVVM 框架,因為實現了數據的雙向綁定,對於大數組、複雜對象會存在性能問題。
可以用來 優化 Angular 應用的性能 的辦法:
d. 移動端
8. 如何看待angular 1.2中引入的controller as 語法?
在 angular 1.2 以前,在 view 上的任何綁定都是直接綁定在 $scope 上的。使用 controllerAs,不需要再注入 $scope,controller 變成了一個很簡單的 javascript 對象(POJO),一個更純粹的 ViewModel。
從源碼實現上來看,controllerAs 語法只是把 controller 這個對象的實例用 as 別名在 $scope 上創建了一個屬性。
if (directive.controllerAs) {
locals.$scope[directive.controllerAs] = controllerInstance;
}
但是這樣做,除了上面提到的使 controller 更加 POJO 外,還可以避免遇到 AngularJS 作用域相關的一個坑(就是上文中 ng-if 產生一級作用域的坑,其實也是 javascript 原型鏈繼承中值類型繼承的坑。因為使用 controllerAs 的話 view 上所有欄位都綁定在一個引用的屬性上,比如 vm.xx,所以坑不再存在)。
不過不引入 $scope 會出現的一個問題是,導致 $emit、 $broadcast、 $on、$watch 等 $scope 下的方法無法使用。這些跟事件相關的操作可以封裝起來統一處理,或者在單個 controller 中引入 $scope,特殊對待。
9. 詳述angular的「依賴注入」
AngularJS 是通過構造函數的參數名字來推斷依賴服務名稱的,通過 toString() 來找到這個定義的 function 對應的字元串,然後用正則解析出其中的參數(依賴項),再去依賴映射中取到對應的依賴,實例化之後傳入。
因為 AngularJS 的 injector 是假設函數的參數名就是依賴的名字,然後去查找依賴項,那如果像下面這樣簡單注入依賴,代碼壓縮後(參數被重命名了),就無法查找到依賴項了。
function myCtrl = ($scope, $http){
...
}
所以,通常會使用下面兩種方式注入依賴(對依賴添加的順序有要求)。
數組注釋法:
myApp.controller("myCtrl", ["$scope", "$http", function($scope, $http){
...
}])
顯式 $inject :
myApp.controller("myCtrl", myCtrl);
function myCtrl = ($scope, $http){
...
}
myCtrl.$inject = ["$scope", "$http"];
對於一個 DI 容器,必須具備三個要素:依賴項的註冊,依賴關係的聲明和對象的獲取。在 AngularJS 中,module 和 $provide 都可以提供依賴項的註冊;內置的 injector 可以獲取對象(自動完成依賴注入);依賴關係的聲明,就是上面的那兩種方式。
10. 如何看待angular 2……
了解有限。
詳細版本可以看這裡:關於 AngularJS 的一些問題 ,裡面有 示例代碼 和 參考資料。
經驗不足,很多問題回答起來都很虛。。。上面回答的這些有的是自己經歷過的一些坑的總結,有的是資料的整理(其實不少問題飛哥 @徐飛 的 博客 和 AngularJS 相關問題下的回答 都已經詳細講過,可自行查閱),僅供參考,歡迎指正~
這還不簡單,你就讓他寫一個列表App
==================================
歌手 [排序] 贊 [排序] 操作Billy Joel 7.5m [編輯] [刪除]Paul McCartney 11.2m [編輯] [刪除]Ziqi Deng 3.6k [編輯] [刪除]Shaopeng 12 [編輯] [刪除]==================================添加/編輯歌手歌手 : __________贊數 : __________[提交] [取消]==================================要求:
- 設計JSON數據結構,其中贊數是實際Number值,但在UI上要對大數簡化成3.6k, 7.5m的格式。 - 實現點擊header按歌手姓名或贊數正反排序 - 添加編輯歌手錶單30分鐘內完成。Ready, Go.如果你做了一個頁面,裡面有不同的directive,上面有一百條信息,並且每條都可以inline edit, 外加每條可以拖曳排序。如果你發現你的頁面載入特別慢,你會如何優化
徐飛的答案寫的很好了,我補充幾個我面試喜歡問的可以以小見大的問題: 1 controller as 和controller 有什麼區別,能解決什麼問題,此題可以考察對scope的理解程度
2 html: {{currentDate()}} js: $scope.currentDate = function(){return new Date();} 這種寫法有沒有問題,此題可考察對digest機制的理解3 directive 如何調用外部函數,如何向函數里傳遞參數,如何expose函數給外部調用全部都能完滿答上的我認為是很有水平了,一題都答不上最多只能算入門級別。
手機碼字,代碼排版不好,見諒能回答angular不好用的情況
1.x已過時,早點棄坑入坑2.0
不才~看看我的github,http://github.com/xianglgd 裡面有兩個關於angular的小項目。
如果能這樣,其實就能表明他的angular水平不錯了量化?看他給angularjs發過多少個PR如何?
能列出使用angular時其中的10個坑就差不多了。
徐飛提出的衡量方式我覺得還是挺好的; 我就獻醜在這裡跟大家交流一下回答; 歡迎補充,交流!首先從小問題開始:
- ng-if跟ng-show/hide的最根本區別就是頁面是否會生成此DOM元素;
- 默認情況下ng-repeat是不允許存在相同值的,這是因為不能管理數據與DOM之間一對一的關係了;但是如果必須存在相同值,可以通過指定 track by 用於區別不同數據
- ng-click中寫的表達式不能使用比如Math.max等JS原生對象上的方法,這是因為執行時如$scope.Math.max
- {{now | "yyyy-MM-dd"}}這種表達式就是filter,可以通過filterProvider自定義
- factory和service,provider都用於註冊服務,不同的是provider只能配置階段注入,factory和service只能運行階段注入;provider通過$get工廠函數穿件新對象,factory通過工廠函數創建新對象,service通過構造函數創建新對象.
下面對大問題進行一下簡述
- angular的數據綁定採用什麼機制?angular 通過監控能事件改變進行綁定;DOM事件(input改變,點擊等),XHR的響應觸發回調;瀏覽器地址變化,計時器觸發回調等;如果以上情況沒有發生,MV改變的可能性不大;
- 兩個平級界面塊a和b,如果a中觸發一個事件,有哪些方式能讓b知道,兩個controller之間進行交互可以通過父作用域數據共享,或者事件的冒泡廣播機制;
- 一個angular應用應當如何良好地分層,將controller中的東西可以向JAVA代碼一樣進行層次劃分,數據請求的dao層,數據處理的service層。很明顯提問者應該是後端開發者,大部分只做前端開發的應該對此理解不深;
- angular應用常用哪些路由庫,各自的區別是什麼? 目前我就使用過angular原生的以及社區開發的ui.router; angular原生的不支持嵌套路由,一個路由只能對應頁面中一個 區域。ui.router 還沒有遇到不支持的功能。
- 如果通過angular的directive規劃一套全組件化體系,可能遇到哪些挑戰?性能,文檔
- 分屬不同團隊進行開發的angular應用,如果要做整合,可能會遇到哪些問題,如何解決 服務衝突,angular將所有模塊的所有服務混入了應用級別的單一命名空間里。開發時規劃好,盡量避免衝突;
- angular的缺點有哪些? 到目前的版本已經發展的相當不錯了。有些路由的限制可以通過第三方庫支持,進行了模塊化拆分,使用更輕量。
- 如何看待angular 1.2中引入的controller as 語法? 尊重更多人的習慣,都能找到自己最舒服的編寫方式
- 詳述angular的「依賴注入」 angular會將依賴的所有模塊上的所有服務混入應用級別的單一命名空間內。所以,模塊間可以相互依賴,不同模塊間的服務可以相互依賴。這有一個問題就是會存在衝突的可能性。在需要使用的地方根據名稱注入。
- 如何看待angular 2…… angular在進步,我們也不能停下,敞開胸懷接受她
事實上,我認為angularjs的程度是這樣分級的:
1.會簡單的使用,但是controller裡面亂七八糟.2.可以自己寫一些服務和過濾器,但是controller裡面還是亂七八糟3.可以使用第三方的指令,但是自己寫指令還是不太行.4.可以自己寫指令,但是不能用angularjs的思想去解決問題5.可以用ang的思想解決問題,並且能做很好的分層分模塊6.已擼完源代碼.順帶艾特一下 @徐飛 大大. 我湊巧看到您在這問題下有回答,也點了贊,可是看了您翻譯的&angular動態構建dom的代碼思路
能寫就好,非要知道茴的八種寫法嗎?angular的依賴注入難道不是過度設計的典範?
歡迎加入angular活躍群,群號碼:315797389
請簡述$compile的用法
基本上懂多少一下子就明白了html: {{currentDate()}} js: $scope.currentDate = function(){return new Date();} 這種寫法有沒有問題?看到某個大師說了這個,求解 @徐飛
推薦閱讀:
※html5 mutation observer 不能監聽元素尺寸變化,還有何用?
※學生關於前端工作的幾個問題?
※CSS布局中聖杯布局與雙飛翼布局的實現思路差異在哪裡?
※老前端勸新手不要學HTML5是什麼心態?
※js入門後,就一直用jquery開發,這樣存在什麼弊端么?