简体   繁体   English

AngularJS 路由链接在重新加载时不起作用

[英]AngularJS routing links don't work on reload

I've been doing a mini project using the TMDb API and AngularJS.我一直在使用TMDb API 和 AngularJS做一个小项目 My Angular routing part works, and i can load the movie details on click.我的 Angular 路由部分工作正常,我可以点击加载电影详细信息。 The click on the homepage takes you to details view and the URL changes to movie/:id/:title and now if the user clicks on another movie present in the details view, the relevant data for the newly clicked movie replaces the previous data.单击主页会将您带到详细信息视图,URL 更改为movie/:id/:title ,现在如果用户单击详细信息视图中的另一部电影,新点击的电影的相关数据将替换之前的数据。 Now if i try going back using the browser the data of the previous movie is not loading up, but the URL shows the previous movie's title.现在,如果我尝试使用浏览器返回,上一部电影的数据不会加载,但 URL 会显示上一部电影的标题。

Along with this error, there's an other bug.除了这个错误,还有一个错误。 When i try reloading the browser it causes 404 Error .当我尝试重新加载浏览器时,它会导致404 错误 If i turn html5Mode(true) this occurs.如果我打开html5Mode(true)就会发生这种情况。 If i disabled html5Mode the page doesn't show relevant information, but shows me an empty template in the view.如果我禁用了html5Mode ,页面不会显示相关信息,但会在视图中显示一个空模板。 I'm just a beginner in AngularJS.我只是 AngularJS 的初学者。 I don't know how to fix this.我不知道如何解决这个问题。 I have mentioned the domain where i've hosted the website.我已经提到了我托管网站的域。 I guess, looking at it would be easier to understand my problem.我想,看着它会更容易理解我的问题。 Hope someone out here could help me.希望这里有人可以帮助我。

PROJECT URL: http://movie-buffs.xyz/项目网址: http : //movie-buffs.xyz/

This is my routing code.这是我的路由代码。

.config(['$routeProvider','$locationProvider', function($routeProvider, $locationProvider){
            $routeProvider
            .when('/',{
                templateUrl:'templates/movies.html'
            })
            .when('/movies/:id/:title',{
                templateUrl:'templates/moviedetails.html'
            })
            .when('/search',{
                templateUrl:'templates/search.html'
            })
            .when('/tv',{
                templateUrl:'templates/tv.html'
            })
            .when('/tv/:id/:title',{
                templateUrl:'templates/tvdetails.html'
            })
            .when('/celebs',{
                templateUrl:'templates/celebs.html'
            })
            .when('/celebs/:id/:name',{
                templateUrl:'templates/celebsdetails.html'
            })
            .when('/contact',{
                templateUrl:'contact_us.html'
            })

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

    $locationProvider.html5Mode(true);
        }]);

Solution 1解决方案1

angularjs provides html5Mode, which makes your app use pushstate-based URL instead of hashtags. angularjs 提供了 html5Mode,它使您的应用程序使用基于推送状态的 URL 而不是主题标签。 However this requires server side support, since the generated urls need to be rendered properly as well.然而,这需要服务器端支持,因为生成的 url 也需要正确呈现。

Simply copy index.html to 404.html, and add this to your app:只需将 index.html 复制到 404.html,并将其添加到您的应用程序中:

angular.module('app', []).config(function($locationProvider) {
  $locationProvider.html5Mode(true);
});

Please find this link for more information请找到链接以获取更多信息

Solution 2解决方案2

open index.html page and in head section add打开 index.html 页面并在 head 部分添加

<base href="/">

Your Angular code enable html5Mode您的 Angular 代码启用html5Mode

 angular.module('main', []).config(['$locationProvider', function($locationProvider) {  
      ...
      $locationProvider.html5Mode(true);
      ...
    });

After doing this, you need to create a .htaccess file on the root of your shared Apache server as your are using apache server add below code执行此操作后,您需要在共享Apache 服务器的根目录上创建一个 .htaccess 文件,因为您正在使用 apache 服务器添加以下代码

Apache Server阿帕奇服务器

RewriteEngine On  
  # If an existing asset or directory is requested go to it as it is
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
  RewriteRule ^ - [L]

  # If the requested resource doesn't exist, use index.html
  RewriteRule ^ /index.html

IIS Server IIS服务器

<rewrite>
  <rules>
    <rule name="AngularJS" stopProcessing="true">
      <match url=".*" />
      <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
      </conditions>
      <action type="Rewrite" url="/" />
    </rule>
  </rules>
</rewrite>

That's it就是这样

Nice page!不错的页面! Try out the html5 mode answer from Curiousdev.试试 Curiousdev 的 html5 模式答案。 And I think you can make the routing simpler.而且我认为您可以使路由更简单。 You could change the routing from你可以改变路由

('/movies/:id/:title')

to

('/movies/:id')

Here is an example on single movie on imdb:以下是 imdb 上单部电影的示例:

http://www.imdb.com/title/tt1219827/?pf_rd_m=A2FGELUUNOQJNL&pf_rd_p=2896364242&pf_rd_r=0QKNGNCGK3XM4PBDN2A0&pf_rd_s=hero&pf_rd_t=15061&pf_rd_i=homepage&ref_=hm_hp_cap_pri_2 http://www.imdb.com/title/tt1219827/?pf_rd_m=A2FGELUUNOQJNL&pf_rd_p=2896364242&pf_rd_r=0QKNGNCGK3XM4PBDN2A0&pf_rd_s=hero&150_rd_hp_hp_hp_hp_pri&15_rd_p_hp=hero=2896364242

They don't provide the title in the url either他们也不在网址中提供标题

Further: If you want to break down the problems in angular routing , remove all extra jquery scripts an so on.进一步:如果您想分解角度路由中的问题,请删除所有额外的 jquery 脚本等等。 Make sure it works before you add the cool gui stuff在添加很酷的 gui 东西之前确保它有效

This is how I do it.我就是这样做的。 In my config.在我的配置中。

.config(['$routeProvider', function ( $routeProvider) {
$locationProvider.html5Mode(false).hashPrefix('');
$routeProvider.otherwise({redirectTo: '/dashboard'});}]);

I divide the html with corresponding js in to folders ex:我将带有相应 js 的 html 划分到文件夹中,例如:

/movie-details/movie-detail.html
/movie-details/movie-detail.js

My movie-details.js should look something like:我的 movie-details.js 应该类似于:

'use strict';
angular.module('myapp')
    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/movies/:Id', {
            templateUrl: 'movie-details/movie-detail.html',
            controller: 'MovieDetails as vm'
        });
    }])
    .controller('MovieDetails', function ($scope, $routeParams) {
        var vm = this;
        vm.movieId= $routeParams.Id;

    });

In the html you wont need any Controller directive.在 html 中,您不需要任何 Controller 指令。 Just:只是:

{{vm.something}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM