Reputation: 305
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
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