red
red

Reputation: 305

AngularJS - Getting an input value and passing it to parent directive scope

Let's say I have a directive and a Controller.

This is my live demo: http://embed.plnkr.co/LfLo0M8tVJyFNpJML5MU/

I'm trying to have an input field inside the Directive's template where you can type in a word and then press Reverse to reverse the string and update the controller's perpective.

But I'm getting:TypeError: Cannot read property 'split' of undefined at Scope.$scope.reverseName on this line (26): $scope.reversedName = $scope.getName.split("").reverse().join("");.

You can either view the plunker link above or here is my code:

app.js:

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

app.directive('myThing', function() {

  return {
    restrict: 'EA',
    controller: 'Controller',
    scope: {
      reverse: "&",
      name: "@",
      getName: "="
    },
    templateUrl: 'template.html'
  };
});

app.controller('Controller', ['$scope', function($scope) {
  $scope.getName = "Rudolph";
  $scope.reversedName = $scope.getName.split("").reverse().join("");
  $scope.reverse = function() {
    $scope.reversedName = $scope.getName.split("").reverse().join("");
    $scope.name = $scope.getName;
  };

}]);

template.html:

<div>Name:
  <input placeholder="Type to reverse the string atop!" type='text' ng-model="getName" />
</div>

<div>Reversed Name: {{reversedName}}</div>

<input type='button' ng-click='reverse()' value='Reverse Name' /> for {{getName}}

and the controller in index.html:

<body ng-controller="Controller">

  <div>
    <strong>Parent Scope:</strong>
    <br /> Name: {{getName}}
    <br />Reversed Name: {{reversedName}}
  </div>

  <br />

  <strong>Isolated Directive's Scope</strong>

  <my-thing reverse="reverseName()"></my-thing>

</body>

What am I doing wrong? Why is my {{getName}} not updating in the parent? But I am not sure how to pass down the info.

Thank you.

Upvotes: 1

Views: 1070

Answers (1)

phix
phix

Reputation: 135

The issue that you are having is that the directive and controller are not attached. Therefore the controller does not know about the $scope.getName variable defined in the ng-model attribute in your directive template. I removed the ng-controller attribute as well because the directive latches a controller in and of itself.

I changed around the template and Angular code and now when you click the Reverse Name button you get the reversed name.

app.js

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

app.directive('myThing', function() {

  var controller = ['$scope', function($scope) {
    $scope.name = "Well dude";
  }];

  return {
    restrict: 'EA',
    controller: 'Controller',
    scope: {
      reverse: "&",
      name: "@",
      getName: "="
    },
    templateUrl: 'template.html'
  };
});

app.controller('Controller', ['$rootScope', '$scope', function($rootScope, $scope) {
  $rootScope.getName = "Rudolph";
  $rootScope.reversedName = $rootScope.getName.split("").reverse().join("");
  $scope.reverse = function() {
    $scope.reversedName = $scope.getName.split("").reverse().join("");
    $scope.name = $scope.getName;
    $rootScope.reversedName = $scope.reversedName;
    $rootScope.getName = $scope.getName;
  };
}]);

template.html

<div>Name:
  <input placeholder="Type to reverse the string atop!" type='text' ng-model="getName" />
</div>

<div>Reversed Name:
  {{reversedName}}
</div>

<input type='button' ng-click='reverse()' value='Reverse Name' /> for {{getName}}

Hope this Helps

Upvotes: 1

Related Questions