1. 程式人生 > >angularJs 多文件動態上傳(刪除其中一個文件的時候,要麽file沒被刪除,要麽刪除了之後,點擊事件失效)

angularJs 多文件動態上傳(刪除其中一個文件的時候,要麽file沒被刪除,要麽刪除了之後,點擊事件失效)

頁面 this 識別 更新 百度 一次 files fileinput type

<div
cacModule.controller(‘CacScriptEditCtrl‘, CacScriptEditCtrl);
    CacScriptEditCtrl.$inject = [‘$uibModalInstance‘, ‘$scope‘, ‘$compile‘, ‘$scope‘, ‘cacScriptService‘, ‘messageService‘, ‘entity‘];

    function CacScriptEditCtrl($uibModalInstance, $scope, $compile, $scope, cacScriptService, messageService, entity) {

        
var vm = this; vm.views = { script: entity.script, scriptList: [], cancel: cancel, //save: save, reduceScript: reduceScript, addScript: addScript, uploadAttach: uploadAttach, files: [] }; function
cancel() { $uibModalInstance.close({action: "cancel"}); } function uploadAttach($file) { vm.views.files = $file; if($file.length>1){ for(var i=0;i<$file.length;i++){ console.log($file[i]); } } }
function reduceScript($index) {

       /**這裏雖然吧type=file(選了文件之後)置為了null,但是執行完vm.views.scriptList.splice($index,1);之後只要是class="file{{$index}}"(之前移除掉的那個$index)的file都會為空
       *主要原因就使我在ng-repeate那裏使用了track by $index,自行百度track by $index
       *如果我不用angular.element(".file"+$index).val(null);這句去置空,而是使用remove直接移除dom(angula.element(".fileDiv"+$index).remove;)
       *會導致angular.element(".fileDiv"+$index)元素的點擊事件失效(之前移除掉的那個$index),因為用了remove,它已經脫離這個頁面了(這裏理解有點難),其原因也是因為用了track by $index;
       *如果不用track by $index的話,直接使用vm.views.sriptList.splice($index,1);就能直接移除
       */
angular.element(
".file" + $index).val(null); //angular.element(".fileDiv"+$index).remove(); vm.views.scriptList.splice($index, 1); } function addScript() { initFileInput(); } var temp = 0; function initFileInput() { temp++; var scriptObj = { scriptParams: temp }; vm.views.scriptList.push(scriptObj); } function init() { //新增 if (vm.views.script == null) { initFileInput(); } else { //編輯 } } init(); }

class="form-group fileDiv{{$index}}" ng-repeat="item in cacScriptEditVm.views.scriptList track by $index">
             <div class="col-sm-4">
                 <input type="file" id="file{{$index}}" class="file{{$index}}" ngf-select ngf-change="cacScriptEditVm.views.uploadAttach($files)"/>
             </div>
             <div class="col-sm-8">
                 <input type="text" name="file" ng-model="item.scriptParams"/>
                 <a class="btn btn-info" ng-click="cacScriptEditVm.views.addScript()"><i class="fa fa-plus"></i> </a>
                 <a class="btn btn-info" ng-click="cacScriptEditVm.views.reduceScript($index)"><i class="fa fa-minus"></i> </a>
             </div>
         </div>

總結

track by是angular1.2後新加入的。ng-repeat會為每一次元素加上一個hashkey $$hashKey來識別每一個元素,當我們從後端重新獲取數據時,即使數據完全一樣,但是由於hashKey不一樣,angular會刪除之前的所有dom,重新生成新的dom。這樣效率就會大大降低。可以理解為ng-repeat默認是 track by $$hashKey的。所以,我們應該使用一些不會變的東西來作為標識,比如後端數據的id.

這樣當重新獲取數據時,由於id沒有變,angular就不會去刪除原來的dom,只會更新其中的內容,不同的id再添加新的dom。效率就能提升了。這相當於react中data-reactid的功能,這樣angular並不比react慢。

特別說明:

1.track by 一定要放在orderBy之後,否則會影響orderBy的效果;

2.當單一數組如["a","a"]有重復元素時,需要使用track by $index來保證兩個元素都會渲染,否則只會渲染一個

angularJs 多文件動態上傳(刪除其中一個文件的時候,要麽file沒被刪除,要麽刪除了之後,點擊事件失效)