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.

2
  • 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. stackoverflow.com/questions/16571003/… Commented Aug 5, 2013 at 1: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). Commented Aug 5, 2013 at 1:42

1 Answer 1

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/

Sign up to request clarification or add additional context in comments.

1 Comment

You're right, that does work. I don't know why I didn't think of that. Anyways, thank you! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.