'ng-repeat' 上的自定义过滤器会覆盖范围
Custom filter on 'ng-repeat' does overwrite the scope
我的目标是用另一个数组的教师姓名替换一个输出数组的教师 ID(f_teacher)。我写了一个自定义过滤器,它应该可以完成工作:
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-repeat':
<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
为什么会这样?
感谢您的宝贵时间:)
第一次通过您的过滤器时,代码采用 f_teacher
id 并将其替换为教师姓名。第二次通过它尝试做同样的事情,除了现在不是在 f_teacher
中获取教师 ID,而是找到教师的名字,所以它不起作用。您可以通过复制 类 而不是直接修改它们来修复它。例如
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
编辑
原始解决方案将触发无限摘要,因为过滤器 returns 对象的新实例每次运行时都会导致 angular 认为某些内容已更改并重新触发摘要。你能不能只用一个 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>
我的目标是用另一个数组的教师姓名替换一个输出数组的教师 ID(f_teacher)。我写了一个自定义过滤器,它应该可以完成工作:
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-repeat':
<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
为什么会这样?
感谢您的宝贵时间:)
第一次通过您的过滤器时,代码采用 f_teacher
id 并将其替换为教师姓名。第二次通过它尝试做同样的事情,除了现在不是在 f_teacher
中获取教师 ID,而是找到教师的名字,所以它不起作用。您可以通过复制 类 而不是直接修改它们来修复它。例如
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
编辑
原始解决方案将触发无限摘要,因为过滤器 returns 对象的新实例每次运行时都会导致 angular 认为某些内容已更改并重新触发摘要。你能不能只用一个 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>