Angular 自定义过滤器未更新 ng-repeat
Angular custom filter not updating ng-repeat
这里有很多关于 ng-repeat
和自定义过滤器的问题,但是 none 解决了我面临的问题。
拿这个:
<div class="row" ng-repeat="row in rows | chunk:columns">
<!-- Now loop over the row chunk to output the column -->
<div
ng-class="{'col-xs-12':row.length<=1,'col-xs-6':row.length>1"
ng-repeat="item in row"
>
{{ item.name }}
</div>
</div>
过滤器 chunk
是我为 return 一大块 $scope.rows
创建的自定义过滤器,它是一个对象数组。
在我更改 $scope.columns
的值之前,它工作正常。此时我希望 ng-repeat 指令将自身添加到摘要循环中以重新绘制,但它没有。
当 $scope.columns
的值发生变化时,如何重新绘制它?
根据评论,块过滤器是:
var _ = require('lodash');
/**
* Chunk an array into pieces
* @param collection
* @param chunkSize
* @returns {array}
*/
var chunk = function (collection, chunkSize)
{
if (!collection || _.isNaN(parseInt(chunkSize, 10)))
{
return [];
}
return _.toArray(
_.groupBy(collection, function (iterator, index)
{
return Math.floor(index / parseInt(chunkSize, 10));
})
);
}
/**
* Angular filter to cache array chunks and return
* x number of chunks from an array via a filter.
*
* @example
* <div ng-repeat="item in items | chunk:2"> ... </div>
* @returns {array}
*/
module.exports = function()
{
return _.memoize(chunk);
// If I console.log(_.memoize(chunk)()) here I get the output
// from the first digest only.
};
$scope.columns
正在由指令更新
/**
* toggleGridView directive
* @returns {object}
*/
module.exports = ['localStorageService', function(localStorageService)
{
return {
replace : true,
template: '<button type="button" ng-click="toggleView()"></button>',
link : function(scope, el, attr) {
scope.gridView = localStorageService.get('itemlistgrid') == "true";
scope.columns = scope.gridView ? 2 : 1;
scope.toggleView = function()
{
localStorageService.set(
'itemlistgrid',
scope.gridView = ! scope.gridView
);
scope.columns = scope.gridView ? 2 : 1;
}
}
}
}];
控制器在指令范围内,因此我可以看到列正在输出正确的值。如果我观看 columns
我可以看到它在更新时发生变化。
我删除了过滤器中缓存的需要,并将逻辑移到了控制器中,正如其他一些关于类似问题的答案中所建议的那样。
/**
* Angular filter to cache array chunks and return
* x number of chunks from an array via a filter.
*
* @example
* <div ng-repeat="item in items | chunk:2"> ... </div>
* @returns {array}
*/
module.exports = function()
{
// Removed the _.memoize caching
return chunk;
};
这阻止了过滤器直接在视图中工作,因为它在每次迭代时调用过滤器修改整个数据集,导致摘要循环中的破坏。
我把它拆下来直接放在控制器里了
// Created items as a private variable in the controller
var items = [];
// Watch for changes to gridView and call toggleGrid
$scope.$watch('gridView', toggleGrid);
function toggleGrid(flag)
{
$scope.rows = $filter('chunk')(items, flag ? 2 : 1);
}
// With a restful resource success callback set the initial state
ItemsResource.index({}, function(data)
{
// Set the private data to the collection of models
items = data.body.models;
// Toggle the grid using the initial state of $scope.gridView
toggleGrid($scope.gridView);
}
这里有很多关于 ng-repeat
和自定义过滤器的问题,但是 none 解决了我面临的问题。
拿这个:
<div class="row" ng-repeat="row in rows | chunk:columns">
<!-- Now loop over the row chunk to output the column -->
<div
ng-class="{'col-xs-12':row.length<=1,'col-xs-6':row.length>1"
ng-repeat="item in row"
>
{{ item.name }}
</div>
</div>
过滤器 chunk
是我为 return 一大块 $scope.rows
创建的自定义过滤器,它是一个对象数组。
在我更改 $scope.columns
的值之前,它工作正常。此时我希望 ng-repeat 指令将自身添加到摘要循环中以重新绘制,但它没有。
当 $scope.columns
的值发生变化时,如何重新绘制它?
根据评论,块过滤器是:
var _ = require('lodash');
/**
* Chunk an array into pieces
* @param collection
* @param chunkSize
* @returns {array}
*/
var chunk = function (collection, chunkSize)
{
if (!collection || _.isNaN(parseInt(chunkSize, 10)))
{
return [];
}
return _.toArray(
_.groupBy(collection, function (iterator, index)
{
return Math.floor(index / parseInt(chunkSize, 10));
})
);
}
/**
* Angular filter to cache array chunks and return
* x number of chunks from an array via a filter.
*
* @example
* <div ng-repeat="item in items | chunk:2"> ... </div>
* @returns {array}
*/
module.exports = function()
{
return _.memoize(chunk);
// If I console.log(_.memoize(chunk)()) here I get the output
// from the first digest only.
};
$scope.columns
正在由指令更新
/**
* toggleGridView directive
* @returns {object}
*/
module.exports = ['localStorageService', function(localStorageService)
{
return {
replace : true,
template: '<button type="button" ng-click="toggleView()"></button>',
link : function(scope, el, attr) {
scope.gridView = localStorageService.get('itemlistgrid') == "true";
scope.columns = scope.gridView ? 2 : 1;
scope.toggleView = function()
{
localStorageService.set(
'itemlistgrid',
scope.gridView = ! scope.gridView
);
scope.columns = scope.gridView ? 2 : 1;
}
}
}
}];
控制器在指令范围内,因此我可以看到列正在输出正确的值。如果我观看 columns
我可以看到它在更新时发生变化。
我删除了过滤器中缓存的需要,并将逻辑移到了控制器中,正如其他一些关于类似问题的答案中所建议的那样。
/**
* Angular filter to cache array chunks and return
* x number of chunks from an array via a filter.
*
* @example
* <div ng-repeat="item in items | chunk:2"> ... </div>
* @returns {array}
*/
module.exports = function()
{
// Removed the _.memoize caching
return chunk;
};
这阻止了过滤器直接在视图中工作,因为它在每次迭代时调用过滤器修改整个数据集,导致摘要循环中的破坏。
我把它拆下来直接放在控制器里了
// Created items as a private variable in the controller
var items = [];
// Watch for changes to gridView and call toggleGrid
$scope.$watch('gridView', toggleGrid);
function toggleGrid(flag)
{
$scope.rows = $filter('chunk')(items, flag ? 2 : 1);
}
// With a restful resource success callback set the initial state
ItemsResource.index({}, function(data)
{
// Set the private data to the collection of models
items = data.body.models;
// Toggle the grid using the initial state of $scope.gridView
toggleGrid($scope.gridView);
}