Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access $viewValue from controller in Angular

Tags:

angularjs

I have a an angular app setup as follows. Ng-repeat containing li elements with 2 inputs each (well more than 2 but for this demo I have 2) .

The directive sets the controller.

HTML

<li ng-repeat="lw in lw_list"   my-lw   ng-model="lw"  >            
    <input my-cell ng-init="init(lane , $index , 'name')"  ng-class="'lib_name inline_div'" type='text'     value="{{ lw.library.name }}" >
    <input my-cell ng-init="init(lane , $index , 'volume')  "ng-class="'number_field'"      type="number"   ng-model='volume' />    
</li>                       

javascript

angular.module('Demo').directive("myCell",  function(CellStore){
    return {
            controller : 'CellCtrl' , 
        };
}) ;


angular.module('Demo').controller('CellCtrl' , function($scope , CellStore){
    $scope.init = function(lane, row, column){
        $scope.row = row  ;
        $scope.column = column ; 
        console.log("init" ,  $scope.$parent );
        CellStore.addCell(  lane.lane,  row, column , $viewValue ) ; 
    } ; 
}) ; 

So the idea is that when each input is created, it will call the init function, which will store the input value in a nested hash (for retrieval later). However I don't know how to access the $viewValue variable (the value that the inputs contain) from within the controller.

like image 972
wobbily_col Avatar asked Dec 11 '22 11:12

wobbily_col


2 Answers

Others have solved your problem, but I don't see an answer to your main question, which is how to access $viewValue from the controller, if you wanted to do so.

What you're really doing is accessing the instance of ngModelController that is attached to each input. If you simply put a name attribute on your form element and on each input within it, their controllers will then be accessible on the $scope. (Since you're using an ng-repeat, you'd need some kind of dynamic naming scheme so you can reach them all. You can also just iterate them.)

Once you've named everything, to get the instance, it's simply:

var instance = $scope.formName.inputName;

And $viewValue should be at:

instance.$viewValue

Once you've got this reference, you can also use the other methods on ngModelController, like

instance.$setValidity();

EDIT: You can play with this, and see how it relates to some validation issues, on this Codepen.

like image 105
XML Avatar answered Jan 06 '23 18:01

XML


As @BoxerBucks says, refactor your code into a link function and do the linking from there. You can also do away with the ng-init approach as the link function is called when the directive is created.

First, I've altered the directive slightly so it takes the column name in the attribute value of my-cell (the lw object and the $index are both on the scope so there's no need to pass them):

<li ng-repeat="lw in lw_list" >            
    <input my-cell="name" ng-class="'lib_name inline_div'" type='text' ng-model="lw.name" >
    <input my-cell="volume" ng-class="'number_field'" ng-model='lw.volume' />    
</li>

Then the link function registers this with CellStore:

app.directive("myCell",  function(CellStore){
    return function(scope, elem, attrs) {
        CellStore.addCell(scope.lw, scope.$index, attrs.myCell);
    };
});

And finally, the addCell method:

app.service('CellStore', function() {
    this.addCell = function(lw, row, column) {
        console.log('add cell:', lw.name, row, column, lw[column]);
    };
});

http://jsfiddle.net/9Lmwj/2/

I wasn't exactly sure on your data structure, but hopefully it's a helpful start.

like image 45
noj Avatar answered Jan 06 '23 16:01

noj