0

After describing my setup, my questions are below in bold.

index.html

<div ng-controller="MyCtrl">
    <user-picker placeholder="Type a name..."></user-picker>
</div>

Setup:

var app = angular.module('app', ['app.directives', 'app.controllers']);
var directives = angular.module('app.directives', []);
var ctrls = angular.module('app.controllers', []);

Controller:

ctrls.controller('MyCtrl', function($scope) {
  $scope.foo = 'this is a foo';
});

Directive:

directives.directive('userPicker', function() {
  return {
    restrict: 'E',
    replace: true,
    scope: {
      placeholder: '@'
    },
    templateUrl: 'file.html',
    link: function postLink($scope, ele, attrs) {
      console.log($scope);
      console.log('[ng] Scope is: ');
      console.log($scope.placeholder);
      console.log($scope.$parent.foo);
  }
});

file.html (the directive):

<span>
  <input placeholder="{{placeholder}}" type="text">
</span>

So what I want to end up with, is generally working:

<span placeholder="Type a name...">
  <input placeholder="Type a name..." type="text">
</span>

The placeholder attribute is correctly resolved.

Is this the right way to accomplish this? Note that the attribute ends up in two places.

Why this odd behavior: Secondly, I am baffled by the results of console.log($scope). The console output reveals the accurately set placeholder attribtue on the $scope object. However, even still, the very next console.log($scope.placeholder) statement returns "undefined". How is this possible, when the console output clearly shows the attribute is set?

My goals are:

  • Move or copy the placeholder attribute from the parent down to the child <input> tag.
  • Have access to the template scope from within linking function.
  • Reference the parent MyCtrl controller that this directive sits within.

I was almost there, until I ran into the odd behavior noted above. Any thoughts are appreciated.

vcardillo
  • 1,646
  • 3
  • 24
  • 29
  • 1
    You're doing it right as far as I can tell. The weirdness with the console has to do with the asynchronous stuff Angular is doing behind the scenes. http://stackoverflow.com/questions/16571003/javascript-console-log-displays-different-values-on-same-object – jdp Aug 05 '13 at 01:31
  • Hmm, interesting. Do you know if there is a way to move attributes down to the children, rather than copying them (as I am ending up with above). – vcardillo Aug 05 '13 at 01:42

1 Answers1

1

Instead of attempting to read this off the scope would reading the attrs work?

Some HTML

<script type="text/ng-template" id="file.html">
    <span>
        <input placeholder="{{placeholder}}" type="text"/>
    </span>
</script>
<body ng-app="app">
<div ng-controller="MyCtrl">
    <user-picker placeholder="Type a name..."></user-picker>
</div>
</body>

Some JS

var app = angular.module('app', ['app.directives', 'app.controllers']);
var directives = angular.module('app.directives', []);
var ctrls = angular.module('app.controllers', []);

ctrls.controller('MyCtrl', function ($scope) {
    $scope.foo = 'this is a foo';
});

directives.directive('userPicker', function () {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            placeholder: '@'
        },
        templateUrl: 'file.html',
        link: function postLink($scope, ele, attrs) {
            console.log($scope);
            console.log('[ng] Scope is: ');
            console.log(attrs["placeholder"]);
            console.log($scope.$parent.foo);
        }
    }
});

A Fiddle

http://jsfiddle.net/Rfks8/

shaunhusain
  • 19,630
  • 4
  • 38
  • 51