I am learning about creating custom angular directives, where I would like to use some two way data binding; however with no luck.
Idea is super simple: We have a list of people, where once I select any of them, I want to display selected person's name (detail) in my directive.
Before I paste a lot of code, here is my example plunker:
https://plnkr.co/edit/xQJAWcYcscOaaNs8VlAI?p=preview
Here is what I have done:
Created Main Controller:
(function() {
"use strict";
var controllerId = 'personController';
angular.module("app").controller(controllerId, ["$timeout", personController]);
function personController($timeout) {
var vm = this;
vm.name = "Janko";
vm.people = returnPeople();
vm.selectedPerson = {};
vm.selectPerson = function (person) {
//function to add a new Person
vm.selectedPerson = person;
console.log(vm.selectedPerson.name);
};
}
function returnPeople() {
return [
{
name: "Janko",
surname: "Hrasko",
age: 24,
gender: "M"
},
{
name: "Jozef",
surname: "Mrkvicka",
age: 26,
gender: "M"
},
{
name: "Janka",
surname: "Kratka",
age: 21,
gender: "F"
}
];
};
})();
Created Directive:
(function () {
"use strict";
var app = angular.module("app");
app.directive('personDetail', personDetail);
function personDetail() {
return {
scope: {
person: "=person"
},
restrict: 'E',
templateUrl: '/js/person/templates/personDetail.html'
}
};
})();
**Created Person Detail Controller: **
(function() {
"use strict";
var controllerId = 'personDetail';
angular.module("app").controller(controllerId, ["$scope", personController]);
function personController($scope) {
var vm = this;
vm.person = $scope.person;
}
})();
Finally - person Detail.html
<div ng-controller="personDetail as vm">
<h3>Selected Name:</h3>
<h3>{{vm.person.name}}</h3>
</div>
Unfortunately, data binding is not working, even though I can see that the item has been selected. What am I doing wrong here?
Edit:
All of your answers have removed the ng-controller from my personDetail.html
, however I would like to keep it (currently it only contains one minor binding, yet I want to add more functionality there such as button clicks etc).
Is it possible to keep the controller?
markup: <person-detail person="vm.selectedPerson"></person-detail>
function personDetailsController($scope) {
var vm = this;
//vm.person = $scope.person;// This will get executed only first time.
//Every time you assigning different object to it. Not changing object.property
}
You can use controller as syntax as follows which also preserve two way binding.
function personDetail() {
return {
scope: {
person: "="
},
bindToController: true,
controller:'personDetailsController',
controllerAs: 'vm',
restrict: 'E',
templateUrl: 'personDetail.html'
}
};