Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm staring my way in AngularJS.

I have created a custom directive:

app.directive('myScroll',function(){
return {
    restrict: 'A',
    transclude: true,

    template: '<div ng-transclude></div>',
    link: function(scope , element , attrs) {

    element.addClass('scroll-pane');

    scope.$watch('tasks', function(newval, oldval){
          if ( newval  ) 
          {

            console.log(newval);
            console.log(newval.length);
        }

    });

        console.log("afer watch exper");
        console.log (tasks);



    }


  };

});

with the following HTML:

<div my-scroll>
        <ul>
            <li data-ng-repeat="task in tasks" class="task-wrapper">
                <div class="task-element">
                    <div class="name">{{task.name}}</div>
                    <div class="text">{{task.action}}</div>
                </div>
            </li>
        </ul>
    </div>

the tasks object is evaluated through a service called by the controller ( if necessary i will post its code).

in the directive code the tasks object is undefined, since i have to get the tasks length to execute more css commands i have to wait for ng-repeat to finish or just wait for tasks variable will be evaluated.

for some reason tasks is always undefined both outside and inside the $watch statement. i can see in the console that "after the watch exper" is printed first and then the "in watch" but still no values. the newval object has [move2:function] but its length property keeps returning 0 but it keeps an array of resources with my tasks.

what am i missing here and how can i execute command when the tasks variable is evaluated?

thanks for the helpers.

share|improve this question
add comment

2 Answers

up vote 3 down vote accepted

You should use scope.tasks to refer the data.

app = angular.module('myApp', []);
app.directive('myScroll', function () {
    return {
        restrict: 'A',
        transclude: true,

        template: '<div ng-transclude></div>',
        link: function (scope, element, attrs) {

            element.addClass('scroll-pane');

            scope.$watch('tasks', function (newval, oldval) {
                if (newval) {
                    console.log(newval);
                    console.log(newval.length);
                }
            });
            console.log("afer watch exper");
            console.log(scope.tasks); //this will log the actual data.
        }
    };
});

function Ctrl($scope) {
    $scope.tasks = [{
        name: "task1",
        action: "action1"
    }]
}
share|improve this answer
 
thanks ! stupid mistake by me... i have one more little question, i can see that the watch expression is called twice, why?? because of the asyc service call to the db? –  RonenIL Jul 28 '13 at 7:49
add comment

Try passing the 3rd parameter - true to $watch:

scope.$watch('tasks', function(newval, oldval){
    if(newval){
        console.log(newval);
        console.log(newval.length);
    }
},true);
share|improve this answer
 
This worked for me, and from the docs I see passing true forces comparison on object equality instead of reference. Do you know why it's needed here? –  thebenedict Jul 29 '13 at 7:37
1  
When you pass true as the 3rd parameter, angular creates a deep copy of the model that's being watched. Also, as the document reads : "To save the value of the object for later comparison, the angular.copy function is used. It also means that watching complex options will have adverse memory and performance implications." So, keeping a watch on huge objects is probably not a good idea. –  CodeHater Jul 29 '13 at 7:42
 
I got stuck on this a few times so I made a plunker to demonstrate the difference: plnkr.co/edit/DHJPwMOg4LZTSk1uiV9z?p=preview –  thebenedict Aug 19 '13 at 7:44
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.