0

I'm working on a page that is made up of 5 directives, for example:

<directive-one></directive-one>
<directive-two></directive-two>
<directive-three></directive-three>
<directive-four></directive-four>
<directive-five></directive-five>

I would like to be able to re-order these on demand so that a user can control how their page looks. The only way I could think of doing that was putting them in an ng-repeat:

$scope.directiveOrder = [{
    name: "directive-one",
    html: $sce.trustAsHtml('<directive-one></directive-one>'),
    order: 1
}, ...

HTML:

<div ng-repeat="directive in directiveOrder" ng-bind-html="directive.html">
    {{directive.html}}
</div>

This will give me the right tags, but they aren't processed as directives by angular. Is there a way around that? I'm assuming it's something to do with $sce not handling it, but I might be way off?

m0ngr31
  • 791
  • 13
  • 29
  • this would be useful to you . . http://stackoverflow.com/questions/19415394/with-ng-bind-html-unsafe-removed-how-do-i-inject-html – Fracedo Oct 15 '15 at 21:31
  • 1
    Possible duplicate of [Rendering directives within $sce.trustAsHtml](http://stackoverflow.com/questions/20623118/rendering-directives-within-sce-trustashtml) – Farzad Yousefzadeh Oct 15 '15 at 21:32
  • You can build a directive that inject html with template, based on input from the user and use $compile – Ziv Weissman Oct 15 '15 at 21:34
  • @FarzadYZ thanks for that link. That did the trick for me. – m0ngr31 Oct 15 '15 at 22:02
  • Alternative way - do not use `ngRepeat` but just plain CSS to reorder your content, namely `order` property from Flexbox (https://css-tricks.com/snippets/css/a-guide-to-flexbox/). – Pavel Horal Oct 15 '15 at 22:10

2 Answers2

1

Try creating a new directive and using $compile to render each directive:

https://jsfiddle.net/HB7LU/18670/ http://odetocode.com/blogs/scott/archive/2014/05/07/using-compile-in-angular.aspx

HTML

<div ng-controller="MyCtrl">
    <button ng-click="reOrder()">Re-Order</button>
    <div ng-repeat="d in directives">
        <render template="d.name"></render>
    </div>
</div>

JS

var myApp = angular.module('myApp',[])
.directive('directiveOne', function() {
    return {
        restrict: 'E',
        scope: {},
        template: '<h1>{{obj.title}}</h1>',
        controller: function ($scope) {
            $scope.obj = {title: 'Directive One'};
        }
    }
})
.directive('directiveTwo', function() {
    return {
        restrict: 'E',
        scope: {},
        template: '<h1>{{obj.title}}</h1>',
        controller: function ($scope) {
            $scope.obj = {title: 'Directive Two'};
        }
    }
})
.directive("render", function($compile){
    return {
        restrict: 'E',
        scope: {
            template: '='
        },
        link: function(scope, element){
            var template = '<' + scope.template + '></' + scope.template + '>';
            element.append($compile(template)(scope));
        }
    }
})
.controller('MyCtrl', function($scope, $compile) {
    $scope.directives = [{
        name: 'directive-one'
    }, {
        name: 'directive-two'
    }];
    $scope.reOrder = function () {
        $scope.directives.push($scope.directives.shift());
        console.log($scope.directives);
    };
});
Cameron
  • 2,427
  • 1
  • 22
  • 27
0

I hope You can easily done it.

var myApp = angular.module('myApp',[])
.directive('directiveOne', function() {
    return {
        restrict: 'E',
        scope: {},
        template: '<h1>{{obj.title}}</h1>',
        controller: function ($scope) {
            $scope.obj = {title: 'Directive One'};
        }
    }
})
.directive('directiveTwo', function() {
    return {
        restrict: 'E',
        scope: {},
        template: '<h1>{{obj.title}}</h1>',
        controller: function ($scope) {
            $scope.obj = {title: 'Directive Two'};
        }
    }
});

myApp.controller('ctrl',function($scope){
    $scope.data = [{name:'directive-one'},{name:'directive-two'}];
});
<html ng-app='myApp'>
  <head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js"></script>
  </head>
  <body ng-controller='ctrl'>
      <div ng-repeat='item in data'>
      <item.name></item.name>
        <directive-one></directive-one>
    </body>
  </html>