Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular directive: using ng-model within isolate scope

I'm having trouble working out how I can define a custom directive that both:

  1. Uses isolate scope, and
  2. Uses the ng-model directive in a new scope within in its template.

Here's an example:

HTML:

<body ng-app="app">
  <div ng-controller="ctrl">
    <dir model="foo.bar"></dir>
    Outside directive: {{foo.bar}}
  </div>
</body>

JS:

var app = angular.module('app',[])
  .controller('ctrl', function($scope){
    $scope.foo = { bar: 'baz' };
  })
  .directive('dir', function(){
    return {
      restrict: 'E',
      scope: {
        model: '='
      },
      template: '<div ng-if="true"><input type="text" ng-model="model" /><br/></div>'
    }
  });

The desired behaviour here is that the input's value is bound to the outer scope's foo.bar property, via the the directive's (isolate) scope model property. That doesn't happen, because the ng-if directive on the template's enclosing div creates a new scope, so it's that scope's model that gets updated, not the directive's scope's. Ordinarily you solve these ng-model issues by making sure there's a dot in the expression, but I can't see any way to do that here. I wondered if I might be able to use something like this for my directive:

{
  restrict: 'E',
  scope: {
    model: {
      value: '=model'
    }
  },
  template: '<div ng-if="true"><input type="text" ng-model="model.value" /><br/></div>'
}

but that doesn't work...

Plunker

like image 287
Duncan Avatar asked Jun 17 '14 14:06

Duncan


People also ask

Can we use NG-model for Div?

NgModel expects the bound element to have a value property, which div s don't have. That's why you get the No value accessor error. I don't know if the input event is supported on all browsers for contenteditable . You could always bind to some keyboard event instead.

What is difference between ng-model and Ng bind directive?

ngModel usually use for input tags for bind a variable that we can change variable from controller and html page but ngBind use for display a variable in html page and we can change variable just from controller and html just show variable.

What is the difference between ng-model and data NG model?

There is no difference between ng-model and data-ng-model if you see in terms of AngularJs. Actually, 'data' used as prefix to validate HTML5 validation. So, it is good practice to use data-ng-model , however, you can use ng-model as well. There is no problem in that also.

Can we use filter in NG-model?

The ng-repeat values can be filtered according to the ng-model in AngularJS by using the value of the input field as an expression in a filter. We can set the ng-model directive on an input field to filter ng-repeat values. The below illustrations describes the approach for the implementation.


1 Answers

You are right - ng-if creates a child scope which is causing a problem when text is entered in the input text field. It creates a shadow property named 'model' in child scope which is a copy of the parent scope variable with the same name - effectively breaking the two-way model binding.

The fix for this is simple. In your template, specify the $parent prefix:

  template: '<div ng-if="true">
                   <input type="text" ng-model="$parent.model" /><br/>
             </div>'

This ensures that it will resolve 'model' from the $parent scope, which you've already setup for two-way model binding through the isolated scope.

In the end, the '.' in ng-model saves the day. I find it useful to think about anything left of the dot as a way for Angular to resolve the property through scope inheritance. Without the dot, resolving the property only becomes an issue when we're assigning scope variables (otherwise, lookups are fine, including read-only {{model}} binding expressions).

like image 193
pixelbits Avatar answered Oct 20 '22 04:10

pixelbits