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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With