AngularJS - Create a directive that uses ng-model AngularJS - Create a directive that uses ng-model angularjs angularjs

AngularJS - Create a directive that uses ng-model


EDIT: This answer is old and likely out of date. Just a heads up so it doesn't lead folks astray. I no longer use Angular so I'm not in a good position to make improvements.


It's actually pretty good logic but you can simplify things a bit.

Directive

var app = angular.module('plunker', []);app.controller('MainCtrl', function($scope) {  $scope.model = { name: 'World' };  $scope.name = "Felipe";});app.directive('myDirective', function($compile) {  return {    restrict: 'AE', //attribute or element    scope: {      myDirectiveVar: '=',     //bindAttr: '='    },    template: '<div class="some">' +      '<input ng-model="myDirectiveVar"></div>',    replace: true,    //require: 'ngModel',    link: function($scope, elem, attr, ctrl) {      console.debug($scope);      //var textField = $('input', elem).attr('ng-model', 'myDirectiveVar');      // $compile(textField)($scope.$parent);    }  };});

Html with directive

<body ng-controller="MainCtrl">  This scope value <input ng-model="name">  <my-directive my-directive-var="name"></my-directive></body>

CSS

.some {  border: 1px solid #cacaca;  padding: 10px;}

You can see it in action with this Plunker.

Here's what I see:

  • I understand why you want to use 'ng-model' but in your case it's not necessary. ng-model is to link existing html elements with a value in the scope. Since you're creating a directive yourself you're creating a 'new' html element, so you don't need ng-model.

EDIT As mentioned by Mark in his comment, there's no reason that you can't use ng-model, just to keep with convention.

  • By explicitly creating a scope in your directive (an 'isolated' scope), the directive's scope cannot access the 'name' variable on the parent scope (which is why, I think, you wanted to use ng-model).
  • I removed ngModel from your directive and replaced it with a custom name that you can change to whatever.
  • The thing that makes it all still work is that '=' sign in the scope. Checkout the docs docs under the 'scope' header.

In general, your directives should use the isolated scope (which you did correctly) and use the '=' type scope if you want a value in your directive to always map to a value in the parent scope.


I took a combo of all answers, and now have two ways of doing this with the ng-model attribute:

  • With a new scope which copies ngModel
  • With the same scope which does a compile on link