I have created a custom directive for dropdown. I want to show/hide UI elements when the ng-change event is fired on that dropdown.
This is the plunkr link to my code.
The 'onCarChange()' method is getting called but the UI elements are not being hidden or shown based on the selection.
I am still learning AngularJS, so if I am taking a wrong approach then kindly let me know.
HTML markup
<div ng-app="RedBlack">
<select-car></select-car> <-- element directive
<p ng-show="vm.showDataGrid">DATA GRID</p>
<button ng-show="!vm.disableRunButton">Run Button</button>
</div>
AngularJS code
angular
.module('RedBlack', [])
.component('selectCar', {
restrict: 'E',
templateUrl: 'select-car.html',
bindings: {
},
transclude: true,
controller: CarsController,
controllerAs: 'vm',
replace: true
})
.controller("CarsController", CarsController);
function CarsController() {
var vm = this;
vm.showDataGrid = true;
vm.disableRunButton = true;
vm.myCars = {
options: [
{ id: '1', name: 'LaFerrari' },
{ id: '2', name: 'Porsche 918' },
{ id: '3', name: 'McLaren P1' }
],
selectedCar: { id: '2', name: 'Porsche 918' }
};
vm.onCarChange = onCarChange;
function onCarChange() {
console.log("Called onCarChange()");
vm.showDataGrid = false;
vm.disableRunButton = false;
return true;
}
}
select-car.html
<div>
<select class="form-control" ng-options="option.name for option in vm.myCars.options track by option.id"
ng-model="vm.myCars.selectedCar"
ng-change="vm.onCarChange()">
</select>
</div
scope for components is always isolate. you have two options. option one is to use a directive instead. (plunkr)
angular
.module('RedBlack.components', [])
.directive('selectCar', function() {
return {
restrict: 'E',
templateUrl: 'select-car.html',
transclude: true,
controller: CarsController,
controllerAs: 'vm'
};
});
If you want to use a component one option is to pass the value into it. (plunkr) Notice it would be better to pass something like a model (e.g. car) into the component and use events for changing the dropdown, but you got the point.
1) define controller on outer scope and pass it into component
<html ng-app="RedBlack" ng-controller="CarsController as vm">
...
<select-car parent="vm"></select-car>
...
</html>
2) bind value to isolate scope of component
angular
.module('RedBlack.components', [])
.component('selectCar', {
restrict: 'E',
templateUrl: 'select-car.html',
bindings: { parent: "=" }, // = means two way data binding
controllerAs: "vm"
});
3) adjust template
<div>
<select class="form-control" ng-options="option.name for option in vm.parent.myCars.options track by option.id"
ng-model="vm.parent.myCars.selectedCar"
ng-change="vm.parent.onCarChange()">
</select>
</div>
Here is my refactor for your code
PLUNKER CODE
index.html
<!DOCTYPE html>
<html ng-app="RedBlack">
<head>
<link rel="stylesheet" href="style.css">
<script src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
<script src="car.module.js"></script>
<script src="selectCar.directive.js"></script>
<script src="script.js"></script>
</head>
<body>
<div id="app" ng-controller='MainController as vm'>
<h1>Hello a car!</h1>
<select-car
on-car-changed='vm.carChange(car)'>
</select-car>
<p ng-show="!vm.showDataGrid">DATA GRID</p>
<p>{{ vm.selected.name }}</p>
<button ng-show="!vm.disableRunButton">Run Button</button>
</div>
</body>
</html>
car.module.js //as main
angular
.module('RedBlack.cars', [])
.controller("MainController", MainController);
function MainController() {
var vm = this;
vm.showDataGrid = true;
vm.disableRunButton = true;
vm.carChange = carChange;
function carChange(car) {
console.log("Called onCarChange()");
console.log(car)
vm.selected = car.name
vm.showDataGrid = false;
vm.disableRunButton = false;
}
}
component
select-car.html
<div>
<select
class="form-control"
ng-options="item as item.name for item in vm.myCars track by item.id"
ng-model="vm.selected"
ng-change="vm.onCarChanged({car: vm.selected})">
</select>
</div>
selectCar.directive.js // must become as select-car.component.js
angular
.module('RedBlack.components', [])
.component('selectCar', {
templateUrl: 'select-car.html',
bindings: {
onCarChanged: '&'
},
controller: [function() {
var vm = this;
vm.myCars = [
{ id: 1, name: 'LaFerrari' },
{ id: 2, name: 'Porsche 918' },
{ id: 3, name: 'McLaren P1' }
];
vm.selected = vm.myCars[0]
}],
controllerAs: 'vm'
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With