0

I want to apply a ngIf directive to a DOM element, this ngIf watch a function and that function check the values of other variables. As the following:

    export class Controller{

    private x: ObjectClass;

        public isDone():boolean{
         return this.x.isY() && this.otherFunction();
        }

        private otherFunction():boolean{
        let result:boolean = true;
        this.array.forEach((value)=>{
        if(!value){
        result = false;}
        });
        return result
        }
    }

//define the state 

  .state('app.first-state', {
        url: '/first-state,
        views: {
          'renderView': {
            template: require('./states/first-state.html'),
            controller: 'Controller as Ctrl',
          }
        }
      })

//in the first-state.html

    <div ng-if="Ctrl.isDone()"></div>

x is an object who is carrying methods and variables.

The x.isY() and this.otherFunction() change its return values to true but the ngIf does not recreate the DOM element. It seems that the digest cycle doesn't watch the x object neither array object. Which makes sense since I am not using them directly into DOM elements. However, the method isDone() runs only when I get into the state or I get out from the state.

I did the following workaround, but I am concerned that there will be a performance issue:

    private isDoneVar:boolean = false;

    //then make my "own digest cycle"
     $interval(() => {
                this.isDoneVar = this.isDone();
            }, 700);
//and in the div
        <div ng-if="Ctrl.isDoneVar"></div>

I have two questoins:

  1. Why does the isDone function run when I enter and leave the state?
  2. Is there any better way to tell angular to run this function each digest cycle run? Or to watch any changes for its internal variables(without adding $watch to each variable)
hex
  • 515
  • 2
  • 4
  • 13
  • 1
    `ng-if="isDone()"` looks for an isDone function in the $scope. It doesn't seem to be on the scope. – JB Nizet Nov 27 '16 at 13:35
  • @JBNizet I used `bindToController` but to not write a lot of code, I skipped this step. The `ngIf` calls the `isDone()` method when I enter and leave the state, so `ngIf` "is seeing" the `isDone` function – hex Nov 27 '16 at 13:41
  • If you want us to find a bug in your real code, post your real code. There is no wau ng-if="isDone()" calls an isDone() method of your controller. It looks for it on the scope. – JB Nizet Nov 27 '16 at 13:45
  • @JBNizet sorry for the confusion. I have edited the question – hex Nov 27 '16 at 13:54
  • Your code should work fine as is. isDone() probably continues returning false, even if you think it doesn't. Or you have an error somewhere: check your console. Hard to help more without a complete reproducible plunkr. Another possibility is that you update the state of the controller behind the back of Angular (for example by not using $http, but a custom ajax library). – JB Nizet Nov 27 '16 at 13:59
  • @JBNizet What I expect is that angular does not know anything about the internal structure of `isDone` function, which means that angular will see that nothing is changed about the `isDone`. But my workaround which runs the function each 700 ms and assign its value to a variable that angular is watching it, is working perfectly fine. – hex Nov 27 '16 at 14:06
  • This assumption of yours is incorrect. Angular will call this method every time it needs to to check if its result has changed, and update the DOM accordingly. That's provided that all the changes that can potentially change its result are done via angular events: ng-xxx event handlers, $http service, $interval, etc. If you're doing something behind the back of angular, then $scope.$apply() must be called. Show the code that updates the state of the controller. – JB Nizet Nov 27 '16 at 14:18
  • @JBNizet Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/129159/discussion-between-hex-and-jb-nizet). – hex Nov 27 '16 at 18:45

0 Answers0