【发布时间】:2017-07-25 04:59:57
【问题描述】:
我有一个改变过滤对象的过滤器。但是当我使用ng-style="item.gridSize"
我的过滤器:(大小网格的算法取自(根据我的需要更改)来自Here
angular.module("custom.modules.photoGrid", []).filter('photoSearch', [function () {
function getGrid(photos){
var output = [];
var HEIGHTS = [];
var COLUMN_WIDTH = 227;
var MARGIN = 6;
var DELTA = 20;
var size = window.innerWidth - 50;
var n_columns = Math.floor(size / (2 * (COLUMN_WIDTH + MARGIN)));
create_columns(n_columns);
var small_images = [];
function create_columns(n) {
HEIGHTS = [];
for (var i = 0; i < n; ++i) {
HEIGHTS.push(0);
}
}
function get_min_column() {
var min_height = Infinity;
var min_i = -1;
for (var i = 0; i < HEIGHTS.length; ++i) {
if (HEIGHTS[i] < min_height) {
min_height = HEIGHTS[i];
min_i = i;
}
}
return min_i;
}
function gridSize(i, is_big) {
var size = {
'margin-left': (MARGIN + (COLUMN_WIDTH + MARGIN) * i)+'px',
'margin-top': (HEIGHTS[Math.floor(i / 2)] * (COLUMN_WIDTH + MARGIN))+'px',
'width': is_big ? (COLUMN_WIDTH * 2 + MARGIN)+'px' : COLUMN_WIDTH+'px',
'height': is_big ? (COLUMN_WIDTH * 2 + MARGIN)+'px' : COLUMN_WIDTH+'px'
};
return size;
}
function createGrid(data){
if (data.length >= 2) {
for(var i = 0; i < data.length; i++){
var column = get_min_column();
if (Math.random() > 0.8) {
data[i]['gridSize'] = gridSize(column * 2, true);
HEIGHTS[column] += 2;
} else {
small_images.push(i);
if (small_images.length === 2) {
data[small_images[0]]['gridSize'] = gridSize(column * 2, false);
data[small_images[1]]['gridSize'] = gridSize(column * 2 + 1, false);
HEIGHTS[column] += 1;
small_images = [];
}
}
}
if (small_images.length) {
column = get_min_column();
data[(data.length-1)]['gridSize'] = gridSize(column * 2, false);
}
}
return data;
}
var grid = createGrid(photos);
return grid;
}
return function(photos, search) {
var filtered = [];
if(!!search){ /**@case1 if only search query is present**/
search = search.toLowerCase();
for(var i = 0; i < photos.length; i++){
if(photos[i].photo_name.toLowerCase().indexOf(search) !== -1){
filtered.push(photos[i]);
}
}
}else {
/**@case2 no query is present**/
filtered = photos;
}
filtered = getGrid(filtered);
return filtered;
}
}]);
HTML:
<input type="text" ng-model="input.value"> <span>{{ results.length }}</span> Photo Found
<div ng-repeat='photo in photos | photoSearch:input.value as results track by photo.id' class="photo-item" ng-style="photo.gridSize">
<img ng-src="/photos/{{photo.url}}">
</div>
一个小解释:
每次ng-model input.value 更改过滤器都会运行并为过滤后的照片数组创建不同的网格。所有维度都写在gridSize 中,这会导致摘要循环。
到目前为止我已经尝试过:我已将 ng-repeat 移至指令中,但这样我无法访问 result.length 和 input.value。
我也尝试过 bindonce 指令,但像 bo-style="photo.gridSize" 一样使用它不会在用户搜索后更改网格(并且在逻辑上是正确的,因为只出价一次,但值发生了变化。
所以我的问题是如何让ng-repeat 分配新的grdiSize 属性而不在摘要循环中运行。
更新: JSFiddle
工作小提琴: JSFiddle
【问题讨论】:
-
嗯,你能创建一个 pnkr 或 fiddle 来让你的问题重现吗?
-
@lin 更新添加了 JSFiddle(你可以在控制台中看到)错误信息
-
我认为您使用 ng-style 的方式不正确。它应该类似于:
ng-style="{'margin-left' : calculationLogic, 'margin-top': calculationLogic}"
标签: javascript css angularjs angularjs-directive angularjs-scope