0

我的目標是將一個輸出數組的teacher-id(f_teacher)替換爲另一個數組的老師名稱。我寫了一個自定義過濾器,是應該做的工作:'ng-repeat'上的自定義過濾器會覆蓋範圍

angular.module('core') 
.filter('replaceId', function() {     //filter, which replaces Id's of one array, with corresponding content of another array 
    return function (t_D, s_D, t_prop, s_prop) {  //data of target, data of source, target property, source property 
     var replacment = {}; 
     var output = []; 
     angular.forEach(s_D, function (item) { 
      replacment[item.id] = item[s_prop];  //replacment - object is filled with 'id' as key and corresponding value 
     }); 
     angular.forEach(t_D, function (item) { 
      item[t_prop] = replacment[item[t_prop]]; //ids of target data are replaced with matching value 
      output.push(item); 
     }); 
     return output; 
    } 
}); 

我使用的是「NG重複」是這樣的:

<tr ng-repeat="class in $ctrl.classes | filter:$ctrl.search | replaceId:$ctrl.teachers:'f_teacher':'prename' | orderBy:sortType:sortReverse"> 
    <td>{{class.level}}</td> 
    <td>{{class.classNR}}</td> 
    <td>{{class.f_teacher}}</td> 
</tr> 

但它只能輸出一個空列。現在奇怪的是:如果我按照調試器的步驟進行操作,它將在第一次執行過濾器時起作用。但是當它再次執行時,它會輸出一個空列。

我注意到過濾器的返回對象覆蓋了$ ctrl.classes - 數組,但通常情況下不應該如此?

這裏是一個plnkr: https://plnkr.co/edit/EiW59gbcLI5XmHCS6dIs?p=preview

這究竟是爲什麼?

感謝您的時間:)

+0

可以重現該問題在plunker?你的過濾器直接在'$ ctrl.classes'中的對象上設置字段。如果你不希望它改變'$ ctrl.classes',那麼你可以做一些類似'angular.copy()'的對象。 – rob

+0

我添加了一個plnkr(見上文)。好的,但我使用了其他自定義過濾器,這些自定義過濾器的工作原理相同(修改數組並返回修改後的數組)並且不覆蓋範圍。爲什麼這個自定義過濾器會這樣做? – JoCa

回答

0

第一次通過你的過濾器的代碼利用f_teacher ID和與老師的名字替換它。第二次通過它嘗試做同樣的事情,除了現在,而不是獲得教師ID在f_teacher它找到老師的名字,所以它不起作用。您可以通過製作類的副本來修復它,而不是直接修改它們。例如

angular.forEach(t_D, function (item) { 
    var itemCopy = angular.copy(item); 
    itemCopy[t_prop] = replacment[itemCopy[t_prop]]; 
    output.push(itemCopy); 
}); 

https://plnkr.co/edit/RDvBGITSAis3da6sWnyi?p=preview

編輯

原液會引發無限消化,因爲過濾器返回對象的新實例每次運行時,這將導致的角度去思考的東西已經改變和重新觸發一個消化。你可以有一個獲取教師名字而不是使用過濾器的getter函數嗎?

$scope.getTeacherName = function(id) { 
    var matchingTeachers = $scope.teachers.filter(function(teacher) { 
    return teacher.id == id; 
    }) 

    //Should always be exactly 1 match. 
    return matchingTeachers[0].prename; 
}; 

然後在HTML,你可以使用它像

<tr ng-repeat="class in classes"> 
    <td>{{class.level}}</td> 
    <td>{{class.classNR}}</td> 
    <td>{{getTeacherName(class.f_teacher)}}</td> 
</tr> 

https://plnkr.co/edit/gtu03gQHlRIMsh9vxr1c?p=preview

+0

謝謝!但是現在我得到了一個[角度10 $摘要()迭代達到。墮胎](http://stackoverflow.com/questions/17116114/how-to-troubleshoot-angular-10-digest-iterations-reached-error)錯誤。我不確定它爲什麼在plnkr中有效,但不在我的應用程序中。自定義過濾器絕對是錯誤原因。 – JoCa

+0

沒關係,plnkr javascript也會拋出一個錯誤。 – JoCa

+0

我在編輯中提出了另一個解決方案 – rob