Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manually update AngularJS view using ControllerAs syntax?

I'm developing a dashboard with sortable, dockable, floatable widgets. One of the controls I'm using generates the floating widgets as HTML at the bottom of the DOM, before the closing body tag. This effectively removes actions done in the window controls from the controller scope they are generated in.

I'm developing this dashboard controller using controllerAs syntax available, but I can't figure out how to effectively update the view with this syntax when an external component does an action that affects the data for the view?

Note: This is not the only I'm facing that forces me to manually update the main view. There are also directives elsewhere on the page that perform actions that impact the view.

Ideally, I would never have to update the view manually, because I would be using all commands that happen within the built in Angular commands affecting digest loop - but this was not an option for me.

So... if I was using $scope I would be able to simply do:

$scope.$digest

Or

$scope.$apply

But how do I achieve the same affect using controller as?

var vm = this;
vm.array = [item, item];
vm.something = something;

//External something changes something on a vm.variable

vm.update! //How??
like image 615
Blunderfest Avatar asked Dec 02 '14 18:12

Blunderfest


1 Answers

With 'as' you are defining the way you will refer to your controller scope in you view.

So this:

<body ng-controller="MainCtrl">
  <p>Hello {{name}}!</p>
</body>

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
});

Is equal to this:

<body ng-controller="MainCtrl as main">
  <p>Hello {{main.name}}!</p>
</body>

Your controller:

app.controller('MainCtrl', function($scope) {
  this.name = 'World';
});

DEMO

So basically you should be able to call this.$digest or this.$apply as you would do on $scope.

UPDATE

After doing some search, I think the correct solution should be using $scope.apply() or $scope.digest().

Main resource:
AngularJS’s Controller As and the vm Variable
There is a comment rising your same question and the author replay:

You can use $scope.$apply() in that case and just inject $scope for that purpose (still using vm for everything else). However, if you switch fro using ajax to using Angular's $http, then you won't need to call $apply as angular's $http does that for you. That's what I recommend

Other resources I found:

  • this vs $scope in AngularJS controllers
  • Angular: Should I use this or $scope
  • Do You Like Your Angular Controllers with or without Sugar?
like image 118
pasine Avatar answered Sep 20 '22 23:09

pasine