3

What scope should I give to my directive so that the input displays the initial value "Toto" ? I don't want to take scope:true

HTML code:

<!doctype html>
<html ng-app="plunker" >
<head>
  <meta charset="utf-8">
  <title>AngularJS Plunker</title>
  <script>document.write('<base href="' + document.location + '" />');</script>
  <link rel="stylesheet" href="style.css">
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
  <script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
   <input customattr type = "text" ng-model="value.name" />   
</body>
</html>

JS code :

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.value = {"name":"Toto", "id":1};

});

    app.directive('customattr', function () {
      return {
          restrict: 'A',
          scope: {
          },
          link: function (scope, element, attrs) {

          } 
      }; 
    });

Plunker here: http://plnkr.co/edit/JxWElWhTeBbNpFHS0wYT

JohnCastle
  • 569
  • 1
  • 5
  • 11

1 Answers1

8

I guess this is one of the things that people bump into quite often with AngularJS directives and scopes. To understand the solution and recommendations that follow we need to understand one thing about AngularJS DOM elements and scopes:

In AngularJS any single DOM element is associated with one and only one scope.

This means that we can't have a subset of attributes on a given element to work with one scope and another subset with a different scope. This is exactly what you are trying to do in your plunker where you expect the ng-model attribute to work with one scope (the one defined on the <body> element by the ng-controller directive) and the customattr with another scope - the isolated one created in a directive).

You've got basically 2 ways out of this situation:

1) Use ng-model="$parent.value.name" to explicitly point the ng-model directive to a certain scope. But this is brittle and not obvious.

2) Drop the isolated scope from the attribute directive. As a rule of thumb I would advice against using isolated scopes in directives that are supposed to be used as attribute ones on the input fields (in conjunction with ng-model). You can still get values of an attribute by using the $parse service.

pkozlowski.opensource
  • 117,202
  • 60
  • 326
  • 286
  • Ok. I understand that the customattr and the ng-model have different scopes but I thought I could get away by using a scope binding "=" on one variable (I didn't know which one). Isn't the main point of the binding "=" to reconciliate 2 different scopes ? The main point is that I want the scope to be restricted so that my directive is more general. – JohnCastle Apr 22 '13 at 11:35
  • @JohnCastle those are 2 different problems. The thing is that by using the scope = {val: '='} syntax you are creating a new, isolated scope on this DOM element and running into a problem as described. – pkozlowski.opensource Apr 22 '13 at 11:39
  • @JohnCastle one more thing - if you could elaborate on your real use-case maybe I could propose a solution. – pkozlowski.opensource Apr 22 '13 at 11:43
  • Yes, the use case is: I want to make a directive that takes the input data in the field, process it and then update the ng-model variable. My main problem is this one : I want to be able to modify the ng-model variable and I don't know how to do it. If I know that the scope variable linked to the input is "toto", I can do scope.$apply(function() { scope.toto = myVal;}); but I am supposed to do in the general case ? attrs.$set("ngModel" myVal); doesn't seem to work. – JohnCastle Apr 22 '13 at 11:59
  • @JohnCastle OK, I see. So, the proper solution has really not much to do with what we are discussing here. The way to go would be to plug into the http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController. Could you post another question describing your use-case? Also indicate what kind of processing you would like to do for a given field. This doc might be also of help for you: http://docs.angularjs.org/guide/forms – pkozlowski.opensource Apr 22 '13 at 12:06
  • I have created a new question : http://stackoverflow.com/questions/16156364/update-scope-with-satellite-data If you have any idea, please let me know – JohnCastle Apr 22 '13 at 20:46