Flex, AngularJS + Masonry, akoenig/angular-deckgri

2020-05-10 08:41发布

问题:

I've been sending this emails: I'm about to release an application for web application security which requires the use of a grid like Masonry. I've tried all, and every single angular module, directives, and different approaches, including CSS based techniques, pure Vanilla JS, and your solution is, one of the best options available online. I found, however a main issue, that affects not only your approach, but every single Angular module or addon.

Issue #1:

Your solution, as any other solution, is based on an array of information that is already handled by angular. In your example case, it would be source="photos". Now, the problem comes when there's 2 different groups of elements. Let's assume, that I have a group of elements that where previously defined in the DOM. In other words:

<div angular-grid>
    <p class="angular-grid-elem">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
    <div class="angular-grid-elem" style="height:500px">Same happens with this content.</div>
    <!-- and here comes more content, which is loaded from an array of information -->
    <div class="angular-grid-elem" ng-repeat="data in data_array">
        <p>{{data.header}}</p>
        <p>{{data.details}}</p>
    </div>
</div>

Now, as you can see in the example, the content inside the main div, , should be all, affected by the masonry layout. Of course, this is pseudo code and I'm aware that the sintaxis of your approach is different. However what I'm trying to represent here, is that your module, would be way better, if you would be able to apply the masonry like grid, including elements which are already present in the DOM/HTML in first place, with elements that are coming from an array.

Issue #2:

There's a second issue I found in multiple angular modules and approaches. What happens if I have 2, 3 or let's say even 16 divs which all of them, present the same masonry like behaviour? I have to admit, I didn't try it with your module, as I couldn't solve the initial problem, that requires the proper handling of the combination of elements that are (1) pre-defined in the HTML, and (2) coming from and ng-repeat function.

A possible approach:

In order to solve the second problem and the first one, at the same time, I have thought that the best approach might be to make use of element classes and elements ids to handle the situation? Why? Because it can easily applied into elements that are already there in the DOM in first place, as well, to elements that are joining or leaving dynamically by the use of a ng-repeat or any other of the angular functions.

Here's an example of what I'm saying:

<div class="angular-grid-dad-one" ng-grid="{'dad': 'angular-grid-dad-one', 'childs': 'angular-grid-elem'}" >
    <p class="angular-grid-elem">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
    <div class="angular-grid-elem" style="height:500px">Same happens with this content.</div>
    <!-- and here comes more content, which is loaded from an array of information -->
    <div class="angular-grid-elem" ng-repeat="data in data_array">
        <p>{{data.header}}</p>
        <p>{{data.details}}</p>
    </div>
</div>

In this case, the main div defines itself as id="angular-grid-dad-one", And also tells the Angular module, that the element angular-grid-dad-one is a container div of a masonry like structure, And that it's childs are marked as angular-grid-elem. As we could see on this line. ng-grid="{'dad': 'angular-grid-dad-one', 'childs': 'angular-grid-elem'}"

This way, it allow us to make use of the Angular module in multiple instances. For example.

<div class="seccion_01" ng-grid="{'dad': 'seccion_01', 'childs': 'seccion_01_child'}" ng-show="seccion == '1'">
    <p class="seccion_01_child">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
    <div class="seccion_01_child" style="height:500px">Same happens with this content.</div>
    <!-- and here comes more content, which is loaded from an array of information -->
    <div class="seccion_01_child" ng-repeat="data in data_array">
        <p>{{data.header}}</p>
        <p>{{data.details}}</p>
    </div>
</div>

<div class="another_container" ng-grid="{'dad': 'another_container', 'childs': 'child_of_container'}" ng-show="seccion == '2'">
    <p class="child_of_container">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
    <div class="child_of_container" style="height:500px">Same happens with this content.</div>
    <!-- and here comes more content, which is loaded from an array of information -->
    <div class="child_of_container" ng-repeat="data in data_array">
        <p>{{data.header}}</p>
        <p>{{data.details}}</p>
    </div>
</div>

<div class="redundant_example" ng-grid="{'dad': 'redundant_example', 'childs': 'childs_of_redundancy'}" ng-show="seccion == '3'">
    <p class="childs_of_redundancy">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
    <div class="childs_of_redundancy" style="height:500px">Same happens with this content.</div>
    <!-- and here comes more content, which is loaded from an array of information -->
    <div class="childs_of_redundancy" ng-repeat="data in data_array">
        <p>{{data.header}}</p>
        <p>{{data.details}}</p>
    </div>
</div>

I have used a Json styled instruction in the ng-grid value in order to explain my point, but it doesn't really have to be Json. It even could be 2 different paramenters:

<div class="dad" ng-grid-dad="dad" ng-grid-childs="childs" ng-show="seccion == '3'">
    <p class="childs">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
    <div class="childs" style="height:500px">Same happens with this content.</div>
    <!-- and here comes more content, which is loaded from an array of information -->
    <div class="childs" ng-repeat="data in data_array">
        <p>{{data.header}}</p>
        <p>{{data.details}}</p>
    </div>
</div>

As well, regarding the infinite scroll that you have created, you would be able to load more elements, triggering the infinite scroll, and loading only elements from one specific array, of course. Please let me know if I can help further, I would like to integrate your module into my application.

And let's hope that by the next implementation of HTML and CSS we have this situation fully under control by the next generation of browsers, I'm aware of the work it takes to make this grids in Javascript.

回答1:

Actually, I am gonna go out on a limb and say that flex-wrap: wrap will fix the issue.

.holder {
flex-wrap: wrap
-moz-columns: 2 auto;
box-sizing: border-box;
display: flex;
padding: 0 40px;
width: 100%;
}