jgravois jgravois - 3 months ago 7
AngularJS Question

AngularJS: Changing Routes Based on Drop-Down Not Working

I am working on a project that will ultimately be responsive and the navigation will collapse down to a select control, so I found an article on Google about this. I learned that the ng-change does not fire an angular event but it was suggested that adding a ng-click to the option tags would replace that void.

As I built my POC, the first thing I realized is that my copying-and-pasting the go function into each meant the design wasn't DRY (so alarms began sounding off in my head) and probably means this is not the right way to do this.

I continue to build what I understood from the article and it doesn't change the routes.

I built a plunker.

Here's the HTML:

<!DOCTYPE html>
<html ng-app="myApp">

<meta charset="utf-8" />
<title>Proof of Concept</title>
<link data-require="bootstrap-css@*" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />

<select name="naver" id="naver">
<option value="home" ng-click="go('/')">Home</option>
<option value="first" ng-click="go('/first')">First</option>
<option value="second" ng-click="go('/second')">Second</option>
<div ng-view=""></div>
<script data-require="angular.js@1.2.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js" data-semver="1.2.16"></script>
<script data-require="angular-route@*" data-semver="1.2.14" src="http://code.angularjs.org/1.2.14/angular-route.js"></script>
<script data-require="jquery@*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script data-require="bootstrap@*" data-semver="3.1.1" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="app.js"></script>


and the script:

var app = angular.module("myApp", ['ngRoute']);

.when('/', {
templateUrl: "home.html",
controller: 'HomeController'
.when('/first', {
templateUrl: "first.html",
controller: 'FirstController'
.when('/second', {
templateUrl: "second.html",
controller: 'SecondController'
.otherwise({ redirectTo: '/' });

app.controller('HomeController', function($scope, $location){
$scope.go = function( path ){
app.controller('FirstController', function($scope, $location){
$scope.go = function( path ){
app.controller('SecondController', function($scope, $location){
$scope.go = function( path ){

Any help is greatly appreciated!


You indeed can be more DRY than that. I would:

  1. Remove all go() functions from the views' controllers.

  2. Create a new controller (e.g. NavCtrl) for the navigation "bar".

    <form ng-controller="NavCtrl">
  3. Remove the ngClick directives from the <option> elements (since they don't seem to have any effect - at least in Chrome).

  4. Add an ngModel to the <select> element to keep track of the selected page/view.

  5. Add an ngChange listener to the <select> element to trigger a "redirection" every time the selected page/view changes.

    <select id="naver" name="naver" ng-model="currentPage" ng-change="go(currentPage)">
      <option value="home">Home</option>
      <option value="first">First</option>
      <option value="second">Second</option>
  6. Define the go() function inside the aforementioned NavCtrl controller.

    app.controller('NavCtrl', function NavCtrl($location, $scope) {
      $scope.currentPage = 'home';
      $scope.go = function go(page) {
        $location.path('/' + page);

See, also, this short demo.