0

I am executing an ajax call which fetches some information: <span id="test" abc-dir="test"> </span>

Now, i also have an angular directive that i need to run on the above information returned via ajax.

Problem is: The Angular directive is getting initiated first and tries to find abc-dir in the DOM however since the Ajax call is not complete, it does nothing. How to fire the ajax call first and then call the Angular directive?

My HTML code:

<body ng-app="TestApp" ng-controller="TestCtrl" ng-init="init()"> <div class="test" id="testid"></div> <script> require( ['jquery'], function($) { $.ajax({ type: "GET", url: "....", success: function(data) { document.getElementById('testid').innerHTML = data } }); }); </script>

My Angular directive code is as follows:

angular.module('TestApp', ['ngSanitize']) .directive('abcDir',['abcPropertyMap',function(abcPropertyMap) { return { restrict: 'A', template: function(elm,attrs){ var value = abcPropertyMap[attrs.abcProperty]; return '<span ng-bind-html="'+value+'">x</span>'; } } }])

akoy
  • 173
  • 1
  • 3
  • 9
  • 2
    see this http://stackoverflow.com/questions/21487617/how-do-i-make-angular-js-reevaluate-recompile-inner-html – Callebe Sep 02 '14 at 20:01
  • 2
    Why are you using jquery ajax when angular already provides `$http` ? – PSL Sep 02 '14 at 20:04

2 Answers2

0

Use pre in directive. something like:

pre: function(....) {
}

This will get called before linking.

Bryan Boettcher
  • 4,412
  • 1
  • 28
  • 49
ABOS
  • 3,723
  • 3
  • 17
  • 23
0

return '<span ng-bind-html="'+value+'">x</span>';Dont bind this stuff manually, do it in your template instead. <div>{{value}}</div>. Use a watcher to listen for changes on your propertyMap and apply additional logic as soon it changes (gets loaded through ajax) $scope.$watch(). If you do everything right, you're template will get update automatically. (you may have to use $scope.$apply() if you're not using angular's $http service.

Here is an example how you could write this in angular (code not tested)

the js part:

angular.module('stackoverflow', [])
.controller('questionsCtrl', function($scope, $http) {
    $scope.questions = null;

    $http.get('stackoverflow.com/questions').then(function(questions) {
        $scope.questions = questions;
    });
})
.directive('questionsList', {
    restrict: 'EA',
    templateUrl: 'directives/questionsList.html',
    scope: {
        questions: '=',
    },
    controller: function($scope) {
        $scope.$watch('questions', function(newValue, oldValue) {
            if (newValue !== null) console.log('all questions loaded');
        });
    }
})

and the html:

<!-- index.html -->
<html ng-app="stackoverflow">
<head></head>
<body>
    <div ng-controller="questionsCtrl">
        <questions-list questions="questions"></questions-list>
    </div>
<body>
</html>

<!-- directives/questionsList.html -->
<ul>
    <li ng-repeat="question in question track by $index">
        {{question.title}}
    </li>
</ul>

If you're loading your html through ajax and want to render it on your page (with angular functionality) consider using the ng-includedirective. Otherwise you'll have to compile the html by yourself using the $compileservice:

// example of how to compile html in your controller
// consider thou that $compiling or modifying html from within your controller is considered as bad practice
.controller('someCtrl', function($scope, $element, $compile, $timeout) {
    var scope = $scope.$new();
    scope.question = {title: 'angular stuff'};
    $element.append(
        $compile('<div>{{question.title}}</div>')(scope)
    );

    // will update your html in 2 seconds
    $timeout(function() {
        scope.question.title = 'javascript stuff';
    }, 2000);
});
M K
  • 9,138
  • 7
  • 43
  • 44