Cannot route to other pages in SPA angular with dynamic list

℡╲_俬逩灬. 提交于 2019-12-13 05:09:34

问题


I'm using single page application using angular 1.6. Whenever I use the static list to redirect the routes, it was working fine, but when trying with dynamic list from json, i couldn't get it.

Here is the JSON:

 {
      "People": [{
          "name": "Andrew Amernante",
          "rating": 3,
        },
        {
          "name": "Frank Wang",
          "rating": 5,
        },
        {
          "name": "Chang Wang",
          "rating": 5,
        }
      ]
    }

In Controller, I have these code snippets.

var app = angular.module('myApp', ['ngRoute']);
app.config(['$locationProvider', function($locationProvider) {
    $locationProvider.hashPrefix('');
  }]);
app.config(function($routeProvider) {
  $routeProvider

  .when('/', {
    templateUrl : 'Andrew Amernante.html',
    controller  : 'HomeController'
  })

  .when('/blog', {
    templateUrl : 'Frank Wang.html',
    controller  : 'BlogController'
  })

  .when('/about', {
    templateUrl : 'Sissi Chen.html',
    controller  : 'AboutController'
  })

  .otherwise({redirectTo: '/'});
});

app.controller('mainController', function($scope, $http) {
  $http.get('people.json').
  then(function onSuccess(response) {
    console.log(response);
    $scope.peoples = response.data;

  }).
  catch(function onError(response) {
    console.log(response);
  });
});

And, I wanted to iterate the array and display the three name in list.

<ul class="nav">
      <li class="active" ng-repeat="item in peoples.People track by $index">
                    <a href="#{{item.name}}">{{item.name}}</a>
       </li>
 </ul>

<div ng-view></div>

<script type="text/ng-template" id="Andrew Amernante.html">
    <h1>Home</h1>
    <h3>{{message}}</h3>
  </script>
  <script type="text/ng-template" id="Frank Wang.html">
    <h1>Blog</h1>
    <h3>{{message}}</h3>
  </script>
  <script type="text/ng-template" id="Sissi Chen.html">
    <h1>About</h1>
    <h3>{{message}}</h3>
  </script>

Here is the plunkr code - Plnkr


回答1:


I think you are misunderstanding how routing works in AngularJS:

Any one route can only have a single template and controller. There is a 1 to 1 relationship between a route and a template.

Routes must be accessed buy a fully qualified URL (it's got to have a slash in there somewhere). A hash tag followed by the id attribute of the template tag as your href is not how you access a route.

Additionally, route definitions in AngularJS cannot be defined dynamically. So, you really should consider using one single route to display the data of each of your dynamically loaded objects. You can use route parameters to pass the object. For example:

<script type="text/ng-template" id="person.html">
  <h1>{{title}}</h1>
  <h3>{{message}}</h3>
</script>

Then your route will define that it can accept a route parameter like this:

.when('/people/:person', {
  templateUrl : 'person.html',
  controller  : 'PersonController'
 });

Your navigation will change:

<ul class="nav">
  <li class="active" ng-repeat="item in peoples.People track by $index">
     <a href="/people/{{item.uniqueId}}">{{item.name}}</a>
   </li>
 </ul>

This also requires you to change your data. You must have some unique identifier with no spaces to use the route params:

 {
  "People": [{
      "name": "Andrew Amernante",
      "rating": 3,
      "uniqueId": "andrew-amernante"
    },
    {
      "name": "Frank Wang",
      "uniqueId": "frank-wang",
      "rating": 5,
    },
    {
      "name": "Chang Wang",
      "uniqueId": "chang-wang",
      "rating": 5,
    }
  ]
}

You would then have to search your data in a PersonController to find the item with the same uniqueId

app.controller('PersonController', function($scope, $http, $routeParams) {
  $http.get('people.json').
  then(function onSuccess(response) {
    console.log(response);
    $scope.person = response.data.find(function(item) {
      return item.uniqueId == $routeParams.person;
    });
    $scope.message = person.name;
    $scope.title = "Home"; // or "About" or "Blog";
  }).
  catch(function onError(response) {
    console.log(response);
  });
});



回答2:


Read completely (this shows a quick fix which is not recommended in "real life" apps!)


The error lies in how you're mapping your routes.

Especifically there is an inconsistency between the when and the content which carries the name property of the objects in people.json#People.

For instance the below code expects routes for blog and about

  .when('/blog', { // < -- there is no route for this!
    templateUrl : 'Frank Wang.html',
    controller  : 'BlogController'
  })

  .when('/about', { // < -- there is no route for this!
    templateUrl : 'Sissi Chen.html',
    controller  : 'AboutController'
  })

But you provide (by doing href="#{{item.name}}") these routes: Andrew Amernante, Frank Wang, Chang Wang, and so on... so... the names in the objects contained in People array.

In order to (quickly) fix this change the previous code to:

  .when('/Andrew Amernante', {
    templateUrl : 'Frank Wang.html',
    controller  : 'BlogController'
  })

  .when('/Frank Wang', {
    templateUrl : 'Sissi Chen.html',
    controller  : 'AboutController'
  })
  // add one for every name
  .when('/<every-name>', {
    templateUrl : '<every-name>.html',
    controller  : '<every-controller>'
  })

See this alternative in this forked Plunker.

But in "real" apps this is not a maintainable code.

Instead you should do as suggested in this answer by Pop-A-Stash in which you provide a template and the content changes according to a provided parameter.




回答3:


Whenever we are required to route to certain page by $locationProvider , we have to give the exact address what we configure in the config section.

You are referring to item.name in the json which doesn't match with any of the above configured location mapped with any templates.

As per your problem it depends on your need what exactly you want to modify. If modification in json and html works for you you can go with below approach.

For dynamic loading you can have an extra variable address in the json as a field pointing to blog , about etc.

and in your html you can give it as href="#{{item.address}}".

or

if you dont want to modify the json or html then simply you can change the config to:

.when('/Andrew Amernante', {
templateUrl : 'Andrew Amernante.html',
controller  : 'HomeController'
})
.when('/Frank Wang', {
templateUrl : 'Frank Wang.html',
controller  : 'BlogController'
})
.when('/Sissi Chen', {
templateUrl : 'Sissi Chen.html',
controller  : 'AboutController'
})
.otherwise({redirectTo: '/'});

Hope it will work!!



来源:https://stackoverflow.com/questions/51270206/cannot-route-to-other-pages-in-spa-angular-with-dynamic-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!