背景:
運營系統(tǒng)很多日報月報骗绕,很多列表藐窄,列表有分頁,項目對請求列表和分頁做了封裝酬土。
有一個具體的需求是荆忍,一個列表,打開其中一項撤缴,顯示一個與該項相關的新的列表刹枉,為了返回后不重置列表的搜索條件和保留當前頁數(shù),不打算用打開新的頁面去做新的列表(在新頁面返回后屈呕,頁面數(shù)據(jù)都沒了嘶卧,也懶得用緩存),而是用子控制器的方式凉袱,如下圖:
視圖文件代碼如下(樣式省略):
<div ng-include="'page-header.html'"></div>
<div ng-if="mainList">
............
<div ng-include="'list_temp.html'"></div>
</div>
<!--詳情列表(打開的新列表)-->
<div ng-if="!mainList">
........................
<div ng-controller="subCtrl">
<div ng-include="'list_temp.html'"></div>
</div>
<button ng-click="closePopup()">退出</button>
</div>
</div>
ng-include中的list_temp.html的代碼(樣式省略)如下:
<div class="table-wrap">
<table>
<thead>
..................
</thead>
<tbody>
<tr ng-repeat="item in tableBodyList">
<td ng-repeat="(props, value) in item">{{value}}</td>
.................
</tr>
</tbody>
<tbody ng-if="tableBodyList.length == 0">
<td style="text-align: center">暫無數(shù)據(jù)</td>
</tbody>
</table>
<!--自定義分頁組件芥吟,代碼略-->
<pagination conf="paginationConf"></pagination>
</div>
javascript代碼:
app.controller('parentCtrl', function($scope...){
................
//ng-if的條件值
$scope.mainList = true;
//顯示詳情列表
$scope.showDetailList = function(){
$scope.mainList = false;
}
});
app.controller('subCtrl', function($scope...){
............
});
上述代碼是正確的實現(xiàn)方式,下面說一下我走過的坑:
剛開始在視圖中用ng-show专甩,而不是ng-if钟鸵。 用ng-show在頁面加載時,父涤躲,子控制同時初始化棺耍,同時執(zhí)行了,在打開詳情列表時种樱,我用$scope.$broadcast的方式控制子控制在點擊的時候執(zhí)行蒙袍,
javascript代碼:
app.controller('parentCtrl', function($scope...){
.................
//ng-show的條件值
$scope.mainList = true;
//顯示詳情列表
$scope.showDetailList = function(item){
$scope.mainList = false;
$scope.$broadcast("parentChange", item.id);
}
});
app.controller('subCtrl', function($scope...){
$scope.$on("parentChange", function(e, m) {
$scope.detailId = m;
...............................
});
});
這時父控制器的值會影響子控制器中的值,子控制器界面上操作事件嫩挤,也會調用父控制器中的事件方法害幅,導致混亂,
如果用ng-if岂昭,當true時以现,ng-controller子控制器才會初始化,為false時,在頁面加載的時候不會初始化邑遏,當父控制中的方法把ng-if條件值改為true時佣赖,子控制器執(zhí)行了,這個時候也不需要$scope.$broadcast廣播的方式了记盒,父控制器的值也不會影響子控制器中的值和方法了憎蛤。
下面是ng-if、ng-show纪吮、ng-hide的區(qū)別:
當一個元素被ng-if從DOM中移除(ng-if=false)俩檬,同它關聯(lián)的作用域也會被銷毀。而且當它重新加入DOM中時(ng-if=true)彬碱,會通過原型繼承從它的父作用域生成一個新的作用域豆胸。也就是說ng-if會新建作用域,而ng-show和ng-hide則不會巷疼。
ng-show和ng-hide根據(jù)所給表達式的值來顯示或隱藏HTML元素晚胡,ng-hide功能類似,但作用相反嚼沿。元素的顯示或隱藏是通過改變CSS的display屬性值來實現(xiàn)的估盘。
StackOverflow文章,也有人提問ng-if和ng-show的差別骡尽。這里直接附上:
ng-if
will remove elements from DOM. This means that all your handlers or anything else attached to those elements will be lost. For example, if you bound a click handler to one of child elements, when ng-if
evaluates to false, that element will be removed from DOM and your click handler will not work any more, even after ng-if
later evaluates to true and displays the element. You will need to reattach the handler.
ng-show/ng-hide
does not remove the elements from DOM. It uses CSS styles to hide/show elements (note: you might need to add your own classes). This way your handlers that were attached to children will not be lost.
ng-if
creates a child scope while ng-show/ng-hide
does not
Elements that are not in the DOM have less performance impact and your web app might appear to be faster when using ng-if
compared to ng-show/ng-hide
. In my experience, the difference is negligible. Animations are possible when using both ng-show/ng-hide and ng-if, with examples for both in the Angular documentation.