Question

I am running AngularJS to manage a WebApp and jQuery plugins manipulating DOM (I have no choice for mixing or not both).

Here is my html

<ul jQuery-plugin-directive="{{changeAfterSuccess}}">
    <li ng-repeat="var in varList">
    {{var.attr}}
    </li>
</ul>

Here is the directive

app.directive('jQueryPluginDirective',['$timeout', function (timer) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var myFunctionToExecuteAfterDomMod = function(){
                      //element.myPluginJquery
            }
    }
    };
}]);

Here is my controller :

app.controller('homeController', ['$scope', 'anHttpService', function ($scope, documentService) {
        anHttpService.getVarList().success(function (result) {
            $scope.varList = result.var;
            //$scope.changeAfterSuccess = "sthg";
        });
    }]);

If I use a timer with 0ms on myFunctionToExecuteAfterDomMod, it doesn't work.

If i use attrs.$observe("jQueryPluginDirective", myFunctionToExecuteAfterDomMod) and change changeAfterSuccess. This not work.

The only way I success to use it is to use a timer with more than 10ms. But I don't want to use this ugly solution.

This confirms that myFunctionToExecuteAfterDomMod is called before the {{var.attr}} is changed and that's why it doesn't work...

After searching for a solution for 2hours now, I'm quite desperate, I hope somebody have a good solution.

Bastien

UPDATE

I do the thing how I should now. I am sure of it because when I apply simple DOM modification (like css value change) it does work well. The thing is with the plugin jstree it doesn't work if I don't put a 200ms timer... I'll use the "solution" for now and find a way to not use the plugin after.

Was it helpful?

Solution

You might need to pass a variable as a separate parameter:

app.directive('jQueryPluginDirective',['$timeout', function (timer) {
    return {
        restrict: 'A',
        scope: {
           data: "="
        },
        link: function(scope, element, attrs) {
            var myFunctionToExecuteAfterDomMod = function(){
                      //element.myPluginJquery
            }
            scope.$watch('data', function(newVal, oldVal){
               alert('data changed'); // probably want to use console.log() here instead
            }
        }
    };
}]);

then your HTML would look like this:

<ul jQuery-plugin-directive data="changeAfterSuccess">

UPDATE:

Also, why don't you pass the data and generate html in your directive:

controller HTML:

<jQuery-plugin-directive change="{{changeAfterSuccess}}" data="varList"></jQuery-plugin-directive>

JS in directive

app.directive('jQueryPluginDirective',['$timeout', function (timer) {
    return {
        restrict: 'A',
        scope: {
           data: "=",
           change: "="
        },
        template: "<ul> 
                       <li ng-repeat="var in varList">
                           {{var.attr}}
                       </li>
                   </ul>", // concatenate these lines in to a string
        link: function(scope, element, attrs) {
            var myFunctionToExecuteAfterDomMod = function(){
                      //element.myPluginJquery
            }
            scope.$watch('data', function(newVal, oldVal){
               alert('data changed'); // probably want to use console.log() here instead
            }
        }
    };
}]);

OTHER TIPS

Although everything was said by EliteOctagon allready here is a minimal directive to show you how to use a watcher:

    app.directive('makered', function() {
      return {
        restrict: 'AC',
        controller: function($scope) {
          return $scope.$watch(function(e) {
            $('.item').css('color', rcolor);
          });
        }
      };
    });

Look at this Plunker how to use it, then try to understand EliteOctagons code. (Cant use ajax in a plunker, so I mocked a scope change)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top