質問

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">

  <head>
    <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" />
  </head>

  <body>
    <form>
      <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>
      </select>
    </form>
    <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>
  </body>

</html>

and the script:

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

app.config(function($routeProvider){
    $routeProvider
        .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 ){
        $location.path(path);
    }
});
app.controller('FirstController', function($scope, $location){
    $scope.go = function( path ){
        $location.path(path);
    }
});
app.controller('SecondController', function($scope, $location){
    $scope.go = function( path ){
        $location.path(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>
    </select>
    
  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.

他のヒント

The go() function cannot be called, since the select control is out of the scope of the page controllers.

Try this instead:

plunkr

To Complement the above answers, i have created a directive which will switch routes based on the value selected.

please find the plunk here: plunkr

Here is the code:

  `app.controller('mainController', function($rootScope, $scope) {
  $scope.testArray = [{
    'option': 'home'
  }, {
    'option': 'first'
  }];
  $scope.testModel = $scope.testArray[0].option;
});

app.directive('selectDirective', function() {
  return {
    scope: {
      testModel: '=',
      testArray: '=',
      go: '&'
    },
    require: 'ngModel',
    template: `<select name="testModel" ng-model="testModel" value="option.option" ng-change="Model(testModel)" ng-options="option.option for option in testArray">{{option.option}}</option> 
               <option value="" selected="selected">Select an Item</option>
                </select>`,
    replace: true,
    controller: function($scope, $location) {
      $scope.Model = function(page) {
        $location.path('/' + page.option);
      }
    }
  }
});`

HTML:

'<test-directive dat-options="testArray" dat-heldmodel="testModel"></test-directive>
    <div>Selected: {{testModel}}</div>'
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top