最近在用angularjs做一些東西,由於學藝不精,對angularjs了解不夠,導致經常會不小心掉進一些自己挖的坑里(⊙_⊙),在這里記下來,謹防又踩。
1、angularjs ng-show not working
在頁面中用到了pagination 分頁插件
<pagination total-items="bigTotalItems" page="bigCurrentPage" max-size="maxSize" class="pagination-small" boundary-links="true"></pagination>
。就想說總的條目數bigTotalItems為0的時候就不顯示插件了,ng-show="!!bigTotalItems"。結果ng-show怎么都不起作用。但是如果直接寫ng-show="!!0" 、ng-show="!!80"又是有效的。。。。
然后我又想換一種寫法,在controller里面寫個方法。
$scope.isShow = function{ return !!$scope.bigTotalItems; };
<pagination ng-show="isShow()" total-items="bigTotalItems" page="bigCurrentPage" max-size="maxSize" class="pagination-small" boundary-links="true"></pagination>
還是沒效果,這個時候有點明白了,是scope的問題。於是換一種寫法再試一下:
<div ng-show="!!bigTotalItems"> <pagination total-items="bigTotalItems" page="bigCurrentPage" max-size="maxSize" class="pagination-small" boundary-links="true"></pagination> </div>
果然這個時候就可以了。
pagination指令編寫的時候
.directive('pagination', ['$parse', 'paginationConfig', function($parse, config) { return { restrict: 'EA', scope: { page: '=', totalItems: '=', onSelectPage:' &' }, controller: 'PaginationController', ......
scope的設置為 {},, 這時 directive 創建一個獨立的 scope,沒有原型繼承,directive 不會不小心讀寫父 scope。
所以當我把ng-show="!!bigTotalItems"寫在指令pagination里的時候,pagination已經擁有了一個獨立的scope,是無法讀到父scope里面的bigTotalItems的了。
關於angularjs的scope,這里有篇文章寫得很詳細深入理解 AngularJS 的 Scope。
2、scope.$apply
遇到了一個數據雙向綁定失效的問題,就是明明在controller里面給$scope.×××賦值了,在頁面上愣是沒有update數據。
一開始還不知道是啥原因,然后上網找解決辦法的時候看到說在后面加一句$scope.$apply()就行了,試了一下真的可以,這才發現有$scope.$apply()這個東西。
但是為什么加了$scope.$apply()就可以了?什么時候要用到$scope.$apply()?
上網搜了一下看到這篇文章,解決了我的疑問AngularJS and scope.$apply
$scope.$apply的作用的用來手動通知頁面update綁定的數據的。
一般情況下是不需要我們手動添加這一句代碼的,因為angularjs本身在需要的時候調用,以達到我們所看到的數據雙向綁定的效果。
但是因為我用了一個外部插件uploadify,然后在回調函數那里更新我controller的數據$scope.hasUpload = !$scope.hasUpload.....
因為外部插件本身已經脫離了angularjs的作用域,所以數據雙向綁定在這里沒有效果,只能手動添加$scope.$apply()來通知頁面update數據。
AngularJS and scope.$apply 這篇文章講的要詳細,專業好多,可以幫助我們理解到scope.$apply,還有angularjs數據雙向綁定的原理。。。
3、js按需加載
之前做應用的時候都會在首頁就把全站的js預先加載進來。。。
怎么實現按需加載,在德問上看到一個方案用AngularJS構建單頁應用,怎樣根據需求加載JS文件?
搬到這里來:
首先在$routeProvider里面加resolve屬性,
$routeProvider. when('/phones', { templateUrl: 'partials/phone-list.html', controller: PhoneListCtrl, resolve: PhoneListCtrl.resolve})
然后
function PhoneListCtrl($scope) { //本身不用管,該怎么弄怎么弄 } PhoneListCtrl.resolve = { delay: function($q) { var delay = $q.defer(), load = function(){ $.getScript('/js/xxxxx.js',function(){ delay.resolve(); }); }; load(); return delay.promise; } }