Reputation: 2137
Can i pass NgModelController to directive controller? That's required so i can assign values to model in controller.
This example does not work:
angular
.module('directives.selectBox', [])
.directive('selectBox', selectBox);
function selectBox() {
return {
restrict : 'E',
require : 'ngModel',
scope : {
list : '=',
},
replace : true,
templateUrl : 'common/directives/selectBox/selectBox.html',
controller : SelectBoxController,
};
}
function SelectBoxController(ngModel) {
ngModel.$setViewValue(10); // ???
}
Upvotes: 15
Views: 8403
Reputation: 1577
If you want to affect only model value, $parse method best suit for you because it provides common way to comminicate with outer scope and write code, which does not depends on new scope creation.
angular.directive('selectBox', function($parse){
return {
// your directive stuff
link: function(scope, iElem, iAttrs){
var angularVarSetter = $parse(iAttrs.ngModel).assign;
// in case of no own scope.
angularVarSetter(scope, 100500);
// in case of new scope
angularVarSetter(scope.$parent, 100500);
}
};
});
Upvotes: 0
Reputation: 8314
Pretty simple actually, what you need to do is to get access to the element by injecting $element
into your controller and then calling the .controller()
function on it.
angular
.module('directives.selectBox', [])
.directive('selectBox', selectBox);
function selectBox() {
return {
restrict : 'E',
require : 'ngModel',
scope : {
list : '=',
},
replace : true,
templateUrl : 'common/directives/selectBox/selectBox.html',
controller : SelectBoxController,
};
}
function SelectBoxController($element) {
var ngModel = $element.controller('ngModel');
ngModel.$setViewValue(10); // ???
}
Note that in AngularJS 1.5 the new component()
function was added in addition to the existing directive()
function. This function takes a configuratoin object as second parameter that allows you to directly specify the required controllers, which will then be bound to the component's controller.
Below the same example again, but as component.
angular
.module('directives.selectBox', [])
.component('selectBox',
{
controller: SelectBoxController,
controllerAs: 'vm',
templateUrl : 'common/directives/selectBox/selectBox.html',
bindings: {
list: '=' // though '<' would be better
},
require: {
ngModel: '='
},
// replace: true ==> No longer possible with component
}
);
function SelectBoxController($element) {
$onInit() {
// This function is called automatically whenever the controller is ready
this.ngModel.$setViewValue(10); // ???
}
}
I hope I typed it out ok, this tiny textarea is hardly an IDE :)
Upvotes: 27
Reputation: 20798
First I note your controller is not declared in the module, so it is not called. (might also want to rename it so it's not confusing
angular
.module('directives.selectBox', [])
.controller('SelectBoxController',SelectBoxController)
.directive('selectBox', selectBox);
The directive takes the ng-model. then you can access it using $scope.ngModel within the link function of the directive.
function selectBox() {
return {
restrict : 'E',
require : 'ngModel',
scope : {
list : '=',
},
replace : true,
templateUrl : 'common/directives/selectBox/selectBox.html',
controller : SelectBoxController,
link: function($scope, $element, $attr, ngModel) {
$scope.ngModel.$setViewValue(10);
}
};
here the controller is not even needed actually. Note that you don't necessarily need ngModel, you are passing 'list' as a 2 way binding param here already, so if you want to pass another argument as a parameters, just pass it like your 'list' param in the isolated scope. You should also not be assigning directly to the ng-model or param you pass, but rather to a 'child' element of the object, or you'll see weird behavior as your local object will shadow the original object of the parent scope.
So you may pass 'model.list' as the 'list' param, and then modify 'list' in the local scope which will modify 'model.list' in the parent scope. if you pass 'list' and modify it in the local scope, it will be overriding the list in the parent scope and probably not get your the 2-way binding you expect.
Upvotes: 0