1

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

1 Answer 1

3
+50

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);
}
Sign up to request clarification or add additional context in comments.

4 Comments

yeah it seems is what I need but i have problems to apply on my remote data
I get assignment to undeclared variable $compiled
Do you get some errors in console? Also you can try to wrap your template in <div></div> so it will have only one top level element.
I've been wrapping the template no error in console using firebug, chrome. I added an update on controller because between I use a service to get remote data

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.