简体   繁体   中英

Using ng-model on dynamically created element

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: ng-model绑定

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM