2015-01-29 8 views
13

Próbuję powiązać tablicę page_elements z odpowiednim indeksem .grid-cell w ciągu znaków html, aby był wyświetlany na stronie zamiast w mojej dyrektywie. Przechowuję indeksy danych elementów komórki, a następnie filtruje je w celu pobrania pasujących obiektów typu page_elements.Jak powiązać elementy tablicy według identyfikatora z elementami klasy DOM w dyrektywie?

Jednak nie mogę pozbyć się nadmiarowości ng-repeat w siatce, gdzie jest więcej niż jeden element. Usunięty element jest zastępowany pustym obiektem {}, ale powinien być łączony w celu utrzymywania elementów siatki we właściwych miejscach. Przeniesione elementy powinny być w stanie przeniknąć do innych komórek siatki. Jeśli indeksy zostaną poprawnie przypisane, dyrektywa powinna zadziałać z angular-drag-and-drop-lists, jak to naprawić?

Jak wyświetlić ng-repeat z dopasowanym page_elements tylko raz w danej kratce? na przykład teraz page_elements gdzie grid_id: 2 jest wyświetlany trzy razy w ng-repeat w trzeciej siatce. Jak trwale usunąć obiekt elementu strony i zachować elementy komórki we właściwych miejscach? Przeciągnij również mechanizm & Drop w aktualnym rozwiązaniu.

Obecny fragment kodu i jsfidde:

var app = angular.module('app', ['dndLists']); 
 
app.controller('homeCtrl', function ($scope) { 
 
    $scope.html_string = "<div class='container'><div class='row'><div class='col-xs-12'><div class='row'><div class='col-xs-4 grid-cell'></div><div class='col-xs-4 grid-cell'></div><div class='col-xs-4 grid-cell'></div></div><div class='row'><div class='col-xs-4 grid-cell'></div><div class='col-xs-4 grid-cell'></div><div class='col-xs-4 grid-cell'></div></div></div></div></div>"; 
 

 
    $scope.page_elements = [{ 
 
     "grid_id": 0, 
 
      "position": 0, 
 
      "snippet": "<h4>First Grid 0</h4>", 
 
     "template": "snippet" 
 
    }, { 
 
     "grid_id": 0, 
 
      "position": 1, 
 
      "snippet": "<h2>Second Grid 0</h2>", 
 
     "template": "snippet" 
 
    }, { 
 
     "grid_id": 1, 
 
      "position": 0, 
 
      "snippet": "<h2>First Grid 1</h2>", 
 
     "template": "snippet" 
 
    }, { 
 
     "grid_id": 1, 
 
      "position": 1, 
 
      "snippet": "<h2>Second Grid 1</h2>", 
 
     "template": "snippet" 
 
    }, { 
 
     "grid_id": 2, 
 
      "position": 0, 
 
      "snippet": "<h1>First Grid 2</h1>", 
 
     "template": "snippet" 
 
    }, { 
 
     "grid_id": 2, 
 
      "position": 1, 
 
      "snippet": "<h2>Second Grid 0</h2>", 
 
     "template": "snippet" 
 
    }, { 
 
     "grid_id": 2, 
 
      "position": 2, 
 
      "snippet": "<h2>Third Grid 0</h2>", 
 
     "template": "snippet" 
 
    }, { 
 
     "grid_id": 5, 
 
      "position": 0, 
 
      "snippet": "<h2>Before Last</h2>", 
 
     "template": "snippet" 
 
    }, { 
 
     "grid_id": 5, 
 
      "position": 1, 
 
      "snippet": "<h2>Last</h2>", 
 
     "template": "snippet" 
 
    }]; 
 
    $scope.page_elements_pretty = angular.toJson($scope.page_elements, true); 
 
    $scope.rmElement = function (i) { 
 
     debugger 
 
    }; 
 
}) 
 
    .directive('grid', function ($compile) { 
 
    return { 
 
     restrict: 'E', 
 
     replace: true, 
 
     scope: { 
 
      html_string: '=htmlstring', 
 
      page_elements: '=pageelements' 
 
     }, 
 
     link: function (scope, element, attrs) { 
 
      scope.$watch('html_string', function (html) { 
 
       element.html(html); 
 

 
       var grid_cell = element.find('.grid-cell'); 
 
       for (var celli = 0; celli < grid_cell.length; ++celli) { 
 
        var cell_eli = ''; 
 
        for (var eli = 0; eli < scope.page_elements.length; ++eli) { 
 
         if (scope.page_elements[eli].grid_id === celli) { 
 
          cell_eli += scope.page_elements.indexOf(scope.page_elements[eli]); 
 
         } 
 
        } 
 
        var cell_html = '<div class="layout-grid"><div class="drop-area"><div dnd-list="page_elements">'; 
 
        cell_html += '<div ng-repeat="item in page_elements | cell_elements:\'' + cell_eli + '\'" dnd-draggable="item" dnd-moved="page_elements[page_elements.indexOf(item)].pop()" ng-click="page_elements[page_elements.indexOf(item)] = {}" ng-include="item.template + \'.html\'" dnd-effect-allowed="move"></div>'; 
 
        cell_html += '</div></div></div>'; 
 

 
        $(grid_cell[celli]).empty().append(cell_html); 
 
       } 
 
       $compile(element.contents())(scope); 
 
      }); 
 
     } 
 
    }; 
 
}).filter('cell_elements', function() { 
 
    return function (page_elements, cell_eli_str) { 
 
     var cell_elms = cell_eli_str.split('').map(Number); 
 
     var matched = []; 
 
     for (var i = 0; i < page_elements.length; ++i) { 
 
      for (var j = 0; j < cell_elms.length; ++j) { 
 
       if (i === cell_elms[j]) { 
 
        matched.push(page_elements[i]); 
 
       } 
 
      } 
 
     } 
 
     return matched; 
 
    } 
 
});
.item { 
 
    min-height: 50px; 
 
    padding-left: 0px; 
 
} 
 

 
.drop-layout .layout-grid { 
 
    margin-bottom: 15px; 
 
} 
 

 
.drop-layout .layout-grid [class^=col-] { 
 
    background-color: #eee; 
 
    background-color: rgba(86, 61, 124, .15); 
 
    border: 1px solid #ddd; 
 
    border: 1px solid rgba(86, 61, 124, .2); 
 
} 
 

 
.drop-layout div[dnd-list], .drop-layout div[dnd-list] > div { 
 
    position: relative; 
 
} 
 

 
.drop-layout .drop-area div[dnd-list] { 
 
    min-height: 50px; 
 
    padding-left: 0px; 
 
} 
 

 
.drop-layout .drop-area div { 
 
    background-color: #eee; 
 
    border: 1px solid #ddd; 
 
    display: block; 
 
    padding: 0px; 
 
} 
 

 
.drop-layout .drop-area .dndDragging { 
 
    opacity: 0.7; 
 
} 
 

 
.drop-layout .drop-area .dndDraggingSource { 
 
    display: none; 
 
} 
 

 
.drop-layout .drop-area .dndPlaceholder { 
 
    background-color: #ddd; 
 
    background-color: rgba(86, 61, 124, .2); 
 
    min-height: 48px; 
 
    display: block; 
 
    position: relative; 
 
}
<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> 
 
<script src="https://rawgit.com/marceljuenemann/angular-drag-and-drop-lists/master/angular-drag-and-drop-lists.min.js"></script> 
 

 
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" type="text/css" /> 
 
<div ng-app="app"> 
 
    <div ng-controller="homeCtrl" class="drop-layout"> 
 
    <h1>Grid:</h1> 
 
    <grid htmlstring="html_string" pageelements="page_elements"></grid> 
 
    
 
    <script type="text/ng-template" id="snippet.html"> 
 
     <div class="item">{{item.snippet}} {{item.position}}</div> 
 
    </script> 
 
    <h1>Compile dynamic HTML</h1><h5>How to live preview of filled by elements html?</h5> 
 
    <textarea ng-model="html_string" rows="5" cols="100"></textarea> 
 
    <p>Assign elements to .grid-cells: <pre>{{page_elements}}</pre></p> 
 
    </div> 
 
</div>

+16

Proszę lepiej opisać to, co staramy się osiągnąć z tym. W tej chwili mogę tylko powiedzieć, że jest to całkowicie błędne podejście, nigdy nie powinieneś budować kodu HTML z takich łańcuchów, zwłaszcza gdy celem AngularJS jest pomóc ci łatwiej, używając 'ng-repeat' i' ng-bind'. –

+0

Nie mam lepszego podejścia, ale wciąż szukam. Chciałbym powiązać wstępnie zdefiniowane na serwerze elementy strony (wtyczki) z predefiniowanymi wcześniej na html układem serwera, w celu umożliwienia pracy z [kątowymi listami przeciągania i upuszczania] (https://github.com/marceljuenemann/angular- drag-and-drop-lists), ostatecznie chcę wysłać tylko tablicę 'page_elements' na serwer – luzny

+0

. Potrzebujesz' orderBy' na 'ng-repeat'? Gdzie zamawiasz według 'position'? –

Odpowiedz

1

Nie wiem, czy to jest to, co chcesz, ale po przeczytaniu this post i this post myślę, co rzeczywiście chcesz to ng-bind-html-unsafe.

Dla ng-bind-html-unsafe, odwołujesz się bezpośrednio do zmiennej ng-repeat, a wynik zostanie użyty dla .innerHTML elementu.

Próbowałem edycji jsfiddle, ale nie jestem pewien, mam pożądany efekt: jsfiddle

Powiązane problemy