fefe
fefe

Reputation: 9055

AngularJS directive in $http json response

I try the same thing as here

I retrieve with Ajax server Data which Json contains the markup with a directive and trying to use $compile to fire up this one but at this point without any luck

here is my controller where I try use $compile

angular.module('blancAppApp')
  .controller('SlugCtrl', function ($scope, WpApi, $compile, $filter, ngProgressLite) {

    // the Content to be rendered.
   $scope.post = [];
   //loading animate starts
   ngProgressLite.start();
   loadRemoteData();

   // load remote data from the server.
   function loadRemoteData() {
   // The WpApiService returns a promise.
        WpApi.getContents()
        .then(
            function( post ) {       
                applyRemoteData( post );       
            });    
    }

     // apply the remote data to the local scope.
    function applyRemoteData( newContents ) {
        var compiled = $compile( newContents )($scope);
        console.log(compiled); // this one shows me the object then object.content contains my masonry directive
       firebug output: <div class="ng-scope">[object Object]</div>
    }



  //loading animate ends
  ngProgressLite.done();        

}).directive('compiled', function($timeout) {
            return {
                restrict: 'E',
                scope: {
                compiled: '=compiled'
            },

            link: function (scope, element, attrs, $timeout) {

            element.append(scope.compiled);
        }
    };
});

the directive which should be called

angular.module('blancAppApp')
  .directive('masonry',  function(scope, element, attrs, $timeout) {
            console.log('asdasd');
            var container = element.querySelector('#grid');
                var msnry = new Masonry( container, {
                // options...
                itemSelector: '.masonry-brick',
                columnWidth: 200
            });



        return {
            restrict: 'E'        
        };

  });

the generated view

<div ng-repeat ="article in post " id="#main-content">
    <div ng-bind-html="article.content | unsafe">
        <div ng-controller="ContentCtrl">       
            {{ article.content }}
        </div>
    </div>
</div>

Generated Markup with directive call

<div id="grid" masonry="">
 <div class="masonry-brick "><img src=""... /></div>
 <div class="masonry-brick "><img src=""... /></div>
 <div class="masonry-brick "><img src=""... /></div>
</div>

enter image description here

plunker

Upvotes: 1

Views: 939

Answers (1)

Kostya Shkryob
Kostya Shkryob

Reputation: 2369

You use $compile incorrectly. $compile returns "a link function which is used to bind template". So you need to call returned function. Try:

var compiled = $compile($scope.post)($scope);
console.log(compiled);

Resulting element must be then attached somewhere to DOM document for example with directive:

<!doctype html>
<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.js"></script>
    </head>
    <body ng-app="plunker">
        <div data-ng-controller="SlugCtrl">
            <div id="compiled_content" data-compiled="compiled">

            </div>
        </div>
        <script>
            var app = angular.module('plunker', []);
            app.controller('SlugCtrl', function ($scope, $compile) {
                $scope.some_var = 'var content';
                var template = '<div>{{some_var}}</div>';
                $scope.compiled = $compile(template)($scope);
                $scope.some_var = 'var content canged';
            }).directive('compiled', function() {
                return {
                    restrict: 'A',
                    scope: {
                        compiled: '=compiled'
                    },
                    link: function (scope, element, attrs) {
                        element.append(scope.compiled);
                    }
                };
            });
        </script>
    </body>
</html>

I used element.append(scope.compiled); and not just {{scope.compiled}} because compilation result is object and not a string.

Your applyRemoteData function must be like this:

function applyRemoteData( newContents ) {
    $scope.compiled = $compile('<div>' + newContents + '</div>')($scope);
}

Upvotes: 3

Related Questions