2016-11-22 193 views
8

我需要以下布局Angular Material卡是从左到右插入,在可用宽度的末尾包裹并填充卡之间的任何垂直空间。所有卡具有相同的宽度,但高度不同:Pinterest角度材料布局

enter image description here

这可能与普通的角和CSS?怎么样?


我试着用display:flex做到这一点,但我无法摆脱的垂直空间的:

.cards { 
     display: flex; 
     justify-content: flex-start; 
     flex-wrap: wrap; 
} 

enter image description here


我还发现了一个纯CSS的解决方案,其中解决了空间问题,但具有不同的顺序并且还需要固定的高度: https://codepen.io/michellebarker/pen/zvxpoG

enter image description here


更新

附加要求:

  • 响应式布局:根据与窗口,有更少或更多的列;但他们总是填写所有可用空间(自适应列宽,例如100%,50%等)
  • 的卡插入必须ng-repeat="card in cards | orderBy:order:reverse"
+0

是否有理由将所有内容都放在一个容器中?您可能有三个(列)容器,并将每张卡片插入cardCount%3列吗? – pulekies

+0

一个容器的原因是布局必须是响应式的,因此根据当前分辨率(横向/纵向/屏幕大小),布局具有不同的列数。 –

+2

使用[angular-masonry](https://passy.github.io/angular-masonry/) –

回答

1

工作,我不能帮你的角度解决方案但是,如果您能够将React解决方案转换为Angular解决方案,那么以下算法和代码可能会有所帮助。

因此,为了生成该布局分区的项目为n列,并让默认布局堆叠他们verticaly。然后使用flexbox或百分比宽度布置这些列。

为了使网格响应订阅窗口大小调整事件并计算所需的列数。 columnCount = itemWidth => availableWidth => Math.floor(availableWidth/itemWidth)

看看working React solution。 响应式解决方案是available here

+0

这听起来很有希望 - 但是,将响应版直接作为插件会很棒 - 所以我不会不得不担心更新/维护布局指令... –

0

Flexbox一个网格系统 - 所以你不能填写垂直空间而你wrap - 所以你可以得到的最好的是,如果你也知道高度。

因此,最好的选择是使用允许网格系统Angular Masonry适合此处的用例的系统。

见下面演示:

angular.module("app", ['wu.masonry']).controller("ctrl", function($scope) { 
 
    $scope.cards = [ 
 
    "http://placehold.it/200x100", 
 
    "http://placehold.it/200x100", 
 
    "http://placehold.it/200x200", 
 
    "http://placehold.it/200x300", 
 
    "http://placehold.it/200x100", 
 
    "http://placehold.it/200x200" 
 
    ]; 
 
});
* { 
 
    box-sizing: border-box; 
 
} 
 
.wrapper > .block { 
 
    margin: 0 auto; 
 
} 
 
.grid-item { 
 
    margin-bottom: 5px; 
 
    display: block; 
 
    border: 1px solid #FFA500; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 

 
<!-- Angular masonry scripts --> 
 
<script src="https://npmcdn.com/[email protected]/imagesloaded.pkgd.js"></script> 
 
<script src="https://unpkg.com/[email protected]/dist/masonry.pkgd.js"></script> 
 
<script src="https://passy.github.io/angular-masonry/angular-masonry.js"></script> 
 

 
<div ng-app="app" ng-controller="ctrl" class="wrapper"> 
 

 
    <div class="block" masonry="{columnWidth: 200, gutter: 5, itemSelector:'.grid-item',fitWidth:true}"> 
 
    <div class="masonry-brick" ng-repeat="img in cards track by $index"> 
 
     <img class="grid-item" ng-src="{{img}}"/> 
 
    </div> 
 
    </div> 
 
</div>

+0

非常感谢,这确实是一个非常健全的解决方案!然而,尽管我愿意使用它 - 恐怕很难提前知道这个高度,因为它取决于标题长度和提示的数量,每个条目都有不同的提示,请参阅这里查看完整的案例/网站:http://dev.sonnige-aussichten.ch/ - 你有任何其他想法如何使这项工作最好? –

+0

我很困惑...你不需要知道每个瓷砖的高度我猜,它自己调整,对吧? – kukkuz

1

我创建了一个plunkr,向您展示了如何完成这个概念的证明。

http://plnkr.co/j5yZQHK3D7l3nPJ8cPlB

可以为了完成你想要与需要基本上没有CSS布局的类型利用layout-wrapflex

<div layout="column" layout-wrap> 
    <md-card ng-repeat="card in vm.cards | orderBy:'order':!reverse" flex> 
    ... 
    </md-card> 
</div> 

这样做是调整你的行,以便内容只占所需的空间,但每列的大小保持不变。这是两全其美的!此外,您可以在任何需要的方式(也显示出plunkr)

layout-wrap cards

+0

当仔细观察时,订单不太正确。它应该逐行(从左到右)而不是按列(从上到下)。就像你所期望的那样,它是从'float:left'。除了他们填写垂直空间。你懂我的意思吗? –

1

我需要完全相同的部件订购。但是我找不到一个纯粹的css解决方案,并且flexbox从顶部到底部命令卡片。

有一些基于AngularJS的选项。但是因为我使用的是Angular,所以我无法使用它们。

因此,我开发了一个从左到右定位元素的组件。元素具有相同的宽度和不同的高度。该组件的位置通过计算x和y的每一个元素的坐标:

https://github.com/kodfarki/ng-pinterest-layout

你可能想尝试一下,即使组件正在开发中。

+0

听起来不错!你有在线演示吗? –

+0

您可以使用'ng serve'克隆并运行项目,并在'localhost:4200'上查看它。组件存在小问题。所以,任何帮助将不胜感激。 – Halil