Blunderfest Blunderfest - 6 months ago 34
Javascript Question

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??

Answer

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:

Comments