3

I know similar questions have been asked but they don't apply to my case. I have defined some variables in my controller and display their values in a panel. My controller related to the part is like this:

var vm = this;
vm.wellId = "id";
vm.wellSeq = "sequence";
vm.onWellSelected = onWellSelected;
...
function onWellSelected(wells) {
    ...
    vm.wellId = wells[0]["id"];
    vm.wellSeq = wells[0]["sequence"];
    ...
}

and my html component is like this:

<div plate id="plate-layout"
    on-well-selected="vm.onWellSelected(wells)">
</div>
<ul class="list-group" style="width: 400px; overflow: auto">
    <li class="list-group-item">{{vm.wellId}}</li>
    <li class="list-group-item">{{vm.wellSeq}}</li>
</ul>

I checked the source and set break points in the function onWellSelected: vm.wellId and vm.wellSeq are indeed changed to the correct values after the operation, but the new value cannot be displayed. The definition of plate involves quite a number of other js files so not easy to show here, but plate itself is a directive, with support from two services. What could be the reasons? Thanks!

richards
  • 517
  • 9
  • 27

2 Answers2

7

Sorry I'm new to Angular so took me a while to find this:

$scope.$apply();

Put it after the modification part and then the value is updated on the page.

EDIT:

Just a follow-up: if use this: $scope.$apply() or $scope.$digest(), then I'll get this error: $digest already in progress; but if I remove it, the value won't get updated. So I refer to this post here: Prevent Error, and now it's working fine without the error message. Hope this can help those facing the same issue.

Community
  • 1
  • 1
richards
  • 517
  • 9
  • 27
  • No, that's not required. `$scope.$apply()` is redundant. Moreover since 1.2 `$scope` is not required at all to update controller fields. Use `controller as` syntax instead. You defined the controller incorrectly. See the answer below with correct syntax. – Alexander Elgin Feb 03 '16 at 03:28
  • Sorry there are a lot of files involved so I cannot show everything here, but I'm quite sure my controller should be correct. I established the link between js and html in the controller js file, instead of using ng-app and ng-controller. Now using $apply indeed gives me the desired output. – richards Feb 05 '16 at 03:50
1

var app = angular.module('myApp', []);

app.controller("myCtrl", function () {
  var vm = this;
  vm.wellId = "id";
  vm.wellSeq = "sequence";

  vm.onWellSelected = function (wells) {
    vm.wellId = wells[0]["id"];
    vm.wellSeq = wells[0]["sequence"];
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp">
  <div ng-controller="myCtrl as vm">
    <span>{{vm.wellId}}</span>
    <span>{{vm.wellSeq}}</span>
    <button ng-click="vm.onWellSelected([{id: 'new id', sequence: 'new sequence'}])">Select Well</button>
  </div>
</div>
Alexander Elgin
  • 6,796
  • 4
  • 40
  • 50