0

Angular version: 1.6.0

I have a problem in understanding why I notice different behaviours in notifing to the view a change in a boolean property.

This is the view:

<div ng-app="testApp">
  <div ng-controller="testController as viewModel">

      <h1>
      "IsLoading" value: {{ viewModel.isLoading }}
      </h1>

      <h1>
      "IsLoadingV2" value: {{ viewModel.isLoadingV2 }}
      </h1>

  </div>
</div>

This is the controller:

(function() {

angular.module('testApp', [])
.controller("testController", testController);

function testController($interval) {

  viewModel = this;
  viewModel.isLoading = true;
  viewModel.isLoadingV2 = true;

  viewModel.refreshView = function () {

      viewModel.isLoading = !viewModel.isLoading;
      viewModel.DoNothing();
      viewModel.isLoading = !!viewModel.isLoading;

      viewModel.isLoadingV2 = true;
      viewModel.DoNothing();
      viewModel.isLoadingV2 = false;

  };

  viewModel.DoNothing = function() {
      // 
  }


   var invertPropertyTimer = $interval(function () {

     viewModel.refreshView();

   }.bind(this), 1000);


}

})();

If you run the code above, you will notice that:

  • viewModel.isLoading = !viewModel.isLoading; updates correctly the property, and correctly reflects its change to the view
  • Setting directly true and false doesn't work.

What's the reason?

You can find the full working example on Plunker (last version): https://plnkr.co/edit/HiOQDVBQ7Wztmj5Dr8zb?p=preview

1
  • 2
    See your JS console :) Commented Jan 8, 2017 at 20:55

1 Answer 1

2

Your interval that is called every second is executing the whole refreshView() function every second.

So you start off with isLoading, isLoadingV2 = true.

The first time the function is called:

isLoading = !isLoading // isLoading = false
DoNothing()
isLoading = !isLoading // isLoading = true

isLoadingV2 = true // isLoadingV2 = true
DoNothing()
isLoadingV2 = false; // isLoadingV2 = false

So isLoading at the end of the first refreshView function call is true and isLoadingV2 at the end of the first refreshView function call is false (which is reflected in your view).

Second time refreshView is called (1 second after the first time refreshView was called):

isLoading = !isLoading // isLoading goes from true -> false
DoNothing()
isLoading = !isLoading // isLoading goes from false -> true

viewModel.isLoadingV2 = true //isLoadingV2 = true
DoNothing()
isLoadingV2 = false; //isLoadingV2 = false

And so on.. so you see each time the refreshView is called, isLoading has changed by the end of the function call where as isLoadingV2 is always false at the end of the call so the view.

Sign up to request clarification or add additional context in comments.

6 Comments

Understood! Is the view notified only at the end of the function call?
So, the new question is: how can I achieve the property change of the View inside a function?
@FrancescoB. To answer your first question, I think it's not that the view is only notified at the end of the function call but rather that you set isLoadingV2 to false right after setting it to true. If you add a delay between it, you would probably see the view update. As for your second question, what are you trying to achieve? It seems you could use the first method of changing the iLoading variable to the opposite of what it is.
I tried to set a timeout, but it doesn't work either. I wanted to achieve to have a loading screen to be shown while performing a long time operation.
Link If you run this, you'll see the update on both variables upon the first run.
|

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.