I have a template which creates an input element dynamically on runtime. I want to capture the data entered into this input element into my model. I am trying to achieve this using ng-model. However, its not working. On inspecting the element, I see that correct expression has been binded to ng-model, but it is not updating my model. Here is my code:
Template:
<div child-ng-model="userReg.candidateData.PrimarySkills">
<!-- this div creates an input element on runtime -->
</div>
Directive:
(function (window) {
'use strict';
angular.module('myApp.userRegistration.directive')
.directive('childNgModel', ['$compile', function ($compile) {
return {
restrict: 'A',
scope: {
childNgModel: '@'
},
link: function (scope, element, attrs) {
var el = element.children().eq(0);
el.attr('ng-model', scope.childNgModel);
$compile(el)(scope);
}
}
}]);
})(window);
You can see the correct value being assigned to ng-model below:
The text I enter in the input field is not getting captured by my model (userReg.candidateData.PrimarySkills). Why is this happening? What am I doing wrong here?
The issue is that you are creating an isolated scope in your directive. Thus, the ngModel cannot write to the outer scope variable.
Try the following:
(function (window) {
'use strict';
angular.module('myApp.userRegistration.directive')
.directive('childNgModel', ['$compile', function ($compile) {
return {
restrict: 'A',
scope: true, // create a normal child scope
link: function (scope, element, attrs) {
var el = element.children().eq(0);
el.attr('ng-model', attrs.childNgModel); // just get the attribute value
$compile(el)(scope);
}
}
}]);
})(window);
The model is not available inside the directive.
You have to establish two-way binding first:
scope: {
childNgModel: '='
The change the model of the input to childNgModel
:
el.attr('ng-model', "childNgModel");
$compile(el)(scope);
Now the input updates childNgModel
inside the directive, which itself is linked to userReg.candidateData.PrimarySkills
outside teh directive.
You are passing a model as an interpolated string using '@'.
Try with '=' instead.
If you want the interpolated string contained in the model, you need to surround it with {{ child-ng-model="userReg.candidateData.PrimarySkills" }}
However, using the same name for the directive and the model in the directive is bad practice. You'd better create an attribute especially for the model.
function MyController() { this.userReg = {candidateData: {PrimarySkills:["123", "456", "789"]}}; } function childNgModel($compile) { return { restrict: 'A', scope: { value: '=' }, link: function (scope, element, attrs) { console.log(scope.value); } } } angular.module('app', []); angular.module('app') .controller('MyController', MyController) .directive('childNgModel', childNgModel);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script> <div ng-app="app"> <div ng-controller="MyController as ctrl"> <div child-ng-model value="ctrl.userReg.candidateData.PrimarySkills"> </div> </div> </div>
OR this
function MyController() { this.userReg = {candidateData: {PrimarySkills:["123", "456", "789"]}}; } function childNgModel($compile) { return { restrict: 'A', scope: { value: '@' }, link: function (scope, element, attrs) { console.log(scope.value); } } } angular.module('app', []); angular.module('app') .controller('MyController', MyController) .directive('childNgModel', childNgModel);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script> <div ng-app="app"> <div ng-controller="MyController as ctrl"> <div child-ng-model value="{{ctrl.userReg.candidateData.PrimarySkills}}"> </div> </div> </div>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.