Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I took a combo of all answers, and now have two ways of doing this with the ng-model attribute:</p> <ul> <li>With a new scope which copies ngModel</li> <li>With the same scope which does a compile on link</li> </ul> <p><div class="snippet" data-lang="js" data-hide="true"> <div class="snippet-code snippet-currently-hidden"> <pre class="snippet-code-js lang-js prettyprint-override"><code>var app = angular.module('model', []); app.controller('MainCtrl', function($scope) { $scope.name = "Felipe"; $scope.label = "The Label"; }); app.directive('myDirectiveWithScope', function() { return { restrict: 'E', scope: { ngModel: '=', }, // Notice how label isn't copied template: '&lt;div class="some"&gt;&lt;label&gt;{{label}}: &lt;input ng-model="ngModel"&gt;&lt;/label&gt;&lt;/div&gt;', replace: true }; }); app.directive('myDirectiveWithChildScope', function($compile) { return { restrict: 'E', scope: true, // Notice how label is visible in the scope template: '&lt;div class="some"&gt;&lt;label&gt;{{label}}: &lt;input&gt;&lt;/label&gt;&lt;/div&gt;', replace: true, link: function ($scope, element) { // element will be the div which gets the ng-model on the original directive var model = element.attr('ng-model'); $('input',element).attr('ng-model', model); return $compile(element)($scope); } }; }); app.directive('myDirectiveWithoutScope', function($compile) { return { restrict: 'E', template: '&lt;div class="some"&gt;&lt;label&gt;{{$parent.label}}: &lt;input&gt;&lt;/label&gt;&lt;/div&gt;', replace: true, link: function ($scope, element) { // element will be the div which gets the ng-model on the original directive var model = element.attr('ng-model'); return $compile($('input',element).attr('ng-model', model))($scope); } }; }); app.directive('myReplacedDirectiveIsolate', function($compile) { return { restrict: 'E', scope: {}, template: '&lt;input class="some"&gt;', replace: true }; }); app.directive('myReplacedDirectiveChild', function($compile) { return { restrict: 'E', scope: true, template: '&lt;input class="some"&gt;', replace: true }; }); app.directive('myReplacedDirective', function($compile) { return { restrict: 'E', template: '&lt;input class="some"&gt;', replace: true }; });</code></pre> <pre class="snippet-code-css lang-css prettyprint-override"><code>.some { border: 1px solid #cacaca; padding: 10px; }</code></pre> <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt; &lt;script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"&gt;&lt;/script&gt; &lt;div ng-app="model" ng-controller="MainCtrl"&gt; This scope value &lt;input ng-model="name"&gt;, label: "{{label}}" &lt;ul&gt; &lt;li&gt;With new isolate scope (label from parent): &lt;my-directive-with-scope ng-model="name"&gt;&lt;/my-directive-with-scope&gt; &lt;/li&gt; &lt;li&gt;With new child scope: &lt;my-directive-with-child-scope ng-model="name"&gt;&lt;/my-directive-with-child-scope&gt; &lt;/li&gt; &lt;li&gt;Same scope: &lt;my-directive-without-scope ng-model="name"&gt;&lt;/my-directive-without-scope&gt; &lt;/li&gt; &lt;li&gt;Replaced element, isolate scope: &lt;my-replaced-directive-isolate ng-model="name"&gt;&lt;/my-replaced-directive-isolate&gt; &lt;/li&gt; &lt;li&gt;Replaced element, child scope: &lt;my-replaced-directive-child ng-model="name"&gt;&lt;/my-replaced-directive-child&gt; &lt;/li&gt; &lt;li&gt;Replaced element, same scope: &lt;my-replaced-directive ng-model="name"&gt;&lt;/my-replaced-directive&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Try typing in the child scope ones, they copy the value into the child scope which breaks the link with the parent scope. &lt;p&gt;Also notice how removing jQuery makes it so only the new-isolate-scope version works. &lt;p&gt;Finally, note that the replace+isolate scope only works in AngularJS &gt;=1.2.0 &lt;/div&gt;</code></pre> </div> </div> </p> <p>I'm not sure I like the compiling at link time. However, if you're just replacing the element with another you don't need to do that.</p> <p>All in all I prefer the first one. Simply set scope to <code>{ngModel:"="}</code> and set <code>ng-model="ngModel"</code> where you want it in your template.</p> <p><strong>Update</strong>: I inlined the code snippet and updated it for Angular v1.2. Turns out that isolate scope is still best, especially when not using jQuery. So it boils down to:</p> <ul> <li><p>Are you replacing a single element: Just replace it, leave the scope alone, but note that replace is deprecated for v2.0:</p> <pre><code>app.directive('myReplacedDirective', function($compile) { return { restrict: 'E', template: '&lt;input class="some"&gt;', replace: true }; }); </code></pre></li> <li><p>Otherwise use this:</p> <pre><code>app.directive('myDirectiveWithScope', function() { return { restrict: 'E', scope: { ngModel: '=', }, template: '&lt;div class="some"&gt;&lt;input ng-model="ngModel"&gt;&lt;/div&gt;' }; }); </code></pre></li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload