要制作您概述的设计,我建议执行以下操作:
-
使用过滤器将您的文章“分块”成 9 个一组(类似于 memoized chunking solution)
-
使用自定义指令创建您的“模板”
-
利用响应式固定比例网格系统(例如 cough 我的图书馆 Perfect Bootstrap cough)
Example JSFiddle
步骤1
让我们将您的 JSON 放回标准数组,然后在运行时将其“分块”成 9 个批次。我们创建一个角度filter,然后使用 | chunk 应用它。为了避免无限的摘要循环,我们需要使用变量来记忆函数的结果,在下面的代码中,我们使用字符串'newsGroups'。如果您打算将更多项目加载到数组中,例如无限滚动,则需要更新此变量以刷新记忆结果。把它想象成一个缓存中断。
为简洁起见,我已将您的文章数组剥离为每个元素的 id 和 title 项目。无论如何,我会假设这是来自您的开发环境中的 AJAX 调用。
HTML
<div class="container-fluid" ng-controller="MyCtrl">
<div class="template-container" ng-repeat="newsGroup in NewsListing | chunk:'newsGroups'">
<!-- content here -->
</div>
</div>
JS Chunk 过滤器和文章的基本数组
var myApp = angular.module('myApp', []);
myApp.filter('chunk', function() {
function cacheIt(func) {
cache = {};
return function(arg) {
// if the function has been called with the argument
// short circuit and use cached value, otherwise call the
// cached function with the argument and save it to the cache as well then return
return cache[arg] ? cache[arg] : cache[arg] = func(arg);
};
}
// unchanged from your example apart from we are no longer directly returning this
function chunk(items, chunk_size) {
var chunks = [];
if (angular.isArray(items)) {
if (isNaN(chunk_size))
chunk_size = 9;
for (var i = 0; i < items.length; i += chunk_size) {
chunks.push(items.slice(i, i + chunk_size));
}
} else {
console.log("items is not an array: " + angular.toJson(items));
}
return chunks;
}
// now we return the cached or memoized version of our chunk function
// if you want to use lodash this is really easy since there is already a chunk and memoize function all above code would be removed
// this return would simply be: return _.memoize(_.chunk);
return cacheIt(chunk);
});
myApp.controller('MyCtrl', function($scope) {
$scope.NewsListing = [{
"id": "71b85130-ffe4-11e6-81a4-c1bd97df0d2d",
"title": "Exercitation ullamco laboris"
}, {
"id": "58847180-ffe4-11e6-81a4-c1bd97df0d2d",
"title": "Duis aute irure dolor in reprehenderit"
}, {
"id": "35d2c290-ffe4-11e6-81a4-c1bd97df0d2d",
"title": "Ut enim ad minim"
}, {
"id": "fdbdeb00-ffe3-11e6-81a4-c1bd97df0d2d",
"title": "Ut enim ad minim"
}, {
"id": "df858f30-ffe3-11e6-81a4-c1bd97df0d2d",
"title": "Dolore magna aliqua"
}, {
"id": "bbc619c0-ffe3-11e6-81a4-c1bd97df0d2d",
"title": "Qui officia deserunt mollit anim"
}, {
"id": "8467e800-ffe3-11e6-81a4-c1bd97df0d2d",
"title": "Consectetur adipisicing elit, sed do eiusm"
}, {
"id": "5aea9180-ffe3-11e6-81a4-c1bd97df0d2d",
"title": "Lorem elit, sed do eiusm"
}, {
"id": "418d09c0-ffe3-11e6-81a4-c1bd97df0d2d",
"title": "ALL YOU NEED TO KNOW ABOUT WAREHOUSE"
}, {
"id": "71b85130-ffe4-11e6-81a4-c1bd97df0d2e",
"title": "Exercitation ullamco laboris2"
}, {
"id": "58847180-ffe4-11e6-81a4-c1bd97df0d2e",
"title": "Duis aute irure dolor in reprehenderit2"
}, {
"id": "35d2c290-ffe4-11e6-81a4-c1bd97df0d2e",
"title": "Ut enim ad minim2"
}, {
"id": "fdbdeb00-ffe3-11e6-81a4-c1bd97df0d2e",
"title": "Ut enim ad minim2"
}, {
"id": "df858f30-ffe3-11e6-81a4-c1bd97df0d2e",
"title": "Dolore magna aliqua2"
}, {
"id": "bbc619c0-ffe3-11e6-81a4-c1bd97df0d2e",
"title": "Qui officia deserunt mollit anim2"
}, {
"id": "8467e800-ffe3-11e6-81a4-c1bd97df0d2e",
"title": "Consectetur adipisicing elit, sed do eiusm2"
}, {
"id": "5aea9180-ffe3-11e6-81a4-c1bd97df0d2e",
"title": "Lorem elit, sed do eiusm2"
}, {
"id": "418d09c0-ffe3-11e6-81a4-c1bd97df0d2e",
"title": "ALL YOU NEED TO KNOW ABOUT WAREHOUSE2"
}];
})
第 2 步
在步骤 1 的 HTML 的 content here 注释部分中,我们将应用自定义指令。在实际开发中,我可能会使用单独的文件来保存模板,但是,对于 js fiddle 的约束,我需要将其定义为 text/ng-template script 标签。
您可以看到,第 1 步中 ng-repeat 中的 newsGroup 将使用范围值 items 传递给我们的自定义指令。这将包含最多 9 篇新闻文章。
HTML 指令调用
<div nine-item-news items="newsGroup"></div>
JS 指令定义
myApp.directive('nineItemNews', function() {
return {
restrict: 'A',
replace: true,
templateUrl: '/nine-item-news-template.html',
scope: {
items: '='
}
}
});
HTML 模板
<script type="text/ng-template" id="/nine-item-news-template.html">
<div class="template">
<!-- template content here -->
</div>
</script>
第三步
不久前,我开发了一个 CSS 库,旨在提供响应式固定比例网格元素。这个问题促使我终于把它公之于众。可以把它想象成 bootstrap 的水平 col- 功能,但它是垂直的。
我们将上面的 template content here 注释替换为以下 html,它将加载由步骤 2 中的自定义指令传递给它的项目。我建议您扩展此模板以添加 ng-if 语句以加载/卸载块,同样,我建议使用ng-class 来调整设计,以适应您没有收到完整 9 件物品的情况(即,如果只传递 6 件物品会是什么样子)。或者,使用基于items.length 的ng-switch 并加载完全不同的模板也可以类似地工作。
额外的 CSS 是添加背景颜色并删除引导列的默认填充/边距。
注意:请注意,为了使元素保持它们的比例,它们的overflow 设置为hidden。这在项目具有背景图像时特别有效,但可能会对文本产生意想不到的后果。我的示例包括一个移动响应模板设计,它创建比例为 2:1 的部分。我鼓励您针对您的特定构建和一些屏幕分辨率仔细测试它。
HTML 模板内容
<div class="row" ng-if="items.length">
<div class="col-xs-12 col-md-4 col-no-padding">
<div class="row-xs-6 row-md-12">
<div class="abs-inner bg-darkgrey">
<p ng-bind="items[0].title"></p>
</div>
</div>
</div>
<div class="col-xs-12 col-md-8 col-no-padding">
<div class="row-xs-6">
<div class="abs-inner bg-grey">
<p ng-bind="items[1].title"></p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-md-4 col-no-padding">
<div class="row">
<div class="col-xs-12 col-no-padding">
<div class="row-xs-6">
<div class="abs-inner bg-grey">
<p ng-bind="items[2].title"></p>
</div>
</div>
</div>
<div class="col-xs-12 col-no-padding">
<div class="row-xs-6">
<div class="abs-inner bg-midgrey">
<p ng-bind="items[5].title"></p>
</div>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-md-4 col-no-padding">
<div class="row-xs-6 row-md-12">
<div class="abs-inner bg-white">
<p ng-bind="items[3].title"></p>
</div>
</div>
</div>
<div class="col-xs-12 col-md-4 col-no-padding">
<div class="row">
<div class="col-xs-12 col-no-padding">
<div class="row-xs-6">
<div class="abs-inner bg-grey">
<p ng-bind="items[4].title"></p>
</div>
</div>
</div>
<div class="col-xs-12 col-no-padding">
<div class="row-xs-6">
<div class="abs-inner bg-midgrey">
<p ng-bind="items[6].title"></p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-md-4 col-no-padding">
<div class="row-xs-6 row-md-12">
<div class="abs-inner bg-darkgrey">
<p ng-bind="items[7].title"></p>
</div>
</div>
</div>
<div class="col-xs-12 col-md-8 col-no-padding">
<div class="row-xs-6">
<div class="abs-inner bg-grey">
<p ng-bind="items[8].title"></p>
</div>
</div>
</div>
</div>
CSS
.col-no-padding{
padding-left:0;
padding-right:0;
}
.col-no-padding > .row{
margin-left:0;
margin-right:0;
}
.bg-darkgrey{
background-color:#535353;
}
.bg-midgrey{
background-color:#808080;
}
.bg-grey{
background-color:#959595;
}
.bg-lightgrey{
background-color:#d0d0d0;
}
.bg-white{
background-color:#FFFFFF;
}