【问题标题】:Refresh(F5) ngview with angularJS使用 angularJS 刷新(F5)ngview
【发布时间】:2013-12-04 23:12:25
【问题描述】:

我的 Angular 应用程序有问题。应用程序第一次运行良好,可以在里面导航,但是当我尝试用 F5 刷新页面时它失败了。当 F5 键被按下时,部分被调用到服务器,服务器显然响应部分视图,而不是整个应用程序。

节点路由:

app.get('/', node_routes.welcome);
...
app.get('/profile', pass.ensureAuthenticated, profile_routes.profile);
app.get('/profile/:name', pass.ensureAuthenticated, profile_routes.partials);
app.post('/profile/update', pass.ensureAuthenticated, profile_routes.update);
...

控制器:

exports.profile = function(req, res) {
    var user = req.user;
    Profile.findOne({ username: user.username }, function(err, profile) {
        if (err) { 
            res.redirect('/'); 
        }       
        res.render("profile");
    });  
};  

exports.partials = function(req, res) {
    var name = req.params.name;
    var user = req.user;
    Profile.findOne({ username: user.username }, function(err, profile) {
        if (err) { 
            res.redirect('/'); 
        }       
        res.render(path.join(__dirname + '/../views/profile/' + name));
    });
};

exports.update = function(req, res){
    var profile = req.body;
    delete profile._id;
    Profile.update({'username':profile.username},profile,{safe:true}, function(err, result){
        if(err) {
            console.log('Error updating profile. ' + err);
            res.redirect('/profile');
        }
        else{
            console.log('' + result + ' profile updated for user: ' + profile.username);
            res.redirect('/profile');
        }           
    });
};

角度应用

myApp.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider){
    $routeProvider
       .when('/profile/update', {
           controller: 'myJobOfferListCtrl',
           templateUrl: '/profile/update',
           reloadOnSearch: false
       })
       .when('/profile', {
           controller: 'myJobOfferListCtrl',
           templateUrl: '/profile/dashboard'
       })
       .when('/profile/dashboard', {
           controller: 'myJobOfferListCtrl',
           templateUrl: '/profile/dashboard',
           reloadOnSearch: false
       })
       .when('/profile/offers', {
           controller: 'myJobOfferListCtrl',
           templateUrl: '/profile/offers',
           reloadOnSearch: false
       })      
       .otherwise({redirectTo: '/profile'});
    $locationProvider.html5Mode(true);
}]);

我的个人资料页面

extends layout

block content   
   div.container-fluid(ng-app="appProfile", ng-controller="myJobOfferListCtrl", ng-init="initProfile()")
      div.row-fluid
         div.span3(ng-controller="navBarCtrl")
           div.well.sidebar-nav
             ul.nav.nav-list
               li.well.nav-header.
                  My Profile ({{data.profile.username}})
               li(ng-class="{ active: isActive('dashboard')}") 
                  a(href="/profile/dashboard") Dashboard   
               li(ng-class="{ active: isActive('update')}") 
                  a(href="/profile/update") Update profile
               li.divider
               li.well.nav-header My Jobs
               li(ng-class="{ active: isActive('offers')}") 
                  a(href="/profile/offers") Offers
               li(ng-class="{ active: isActive('application')}") 
                  a(href="/profile/application") Applications
         div.span9(ng-view, ng-cloak)

还有一个示例部分视图页面

   div.row-fluid 
      div(ng-init="initMyOffers()")  
         accordion.span8.offset1(close-others="true")
            accordion-group(ng-repeat="item in data.myJobs", heading="{{item.title}}")
               accordion-heading
                  {{item.title}}
                  i.pull-right.icon-remove-circle.removeButton(ng:click="remove(item)") 
               p {{item.description}}
               hr
               div.footer
                  div.pull-left 
                     i.icon-calendar.calendar
                     {{item.dueDate | date:'d MMMM yyyy'}}
                  div.pull-right 
                     i.icon-user 
                     {{item.author}}

使用 F5 刷新时如何重新加载部分页面?我对 Angular 的期望是,当尝试刷新页面 /profile/dashboard 时,会调用部分 /views/profile/dashboard.jade,但也会调用 views/profile.jade。那么 $scope 呢?

对不起,我有点迷茫...谢谢你的帮助!

【问题讨论】:

  • 一个简单的解决方案是关闭 HTML5 路由:$locationProvider.html5Mode(false)

标签: node.js angularjs express routing


【解决方案1】:

我认为这是一个常见问题,用户应该在您的应用程序中使用F5。我不认为,在按下F5 后可以停止默认浏览器操作。

一个简单的解决方案是将这个或类似的script 添加到每个视图中:

<script>
    if (angular == undefined)
        // alert("It is SPA (Single Page Application) -- do not press F5 anymore, please.");
        window.location.replace("your/main/url");
</script>

以下场景的实现会稍微复杂一些。

  1. 用户点击f5
  2. 服务器发送当前 url current_url 的部分视图
  3. 客户端代码检测到缺少angular并发送请求重定向到current_url
  4. 服务器发送 index.html 文件的修改版本 [例如一些隐藏的输入字段,存储current_url]
  5. 加载 Angular 后,应用程序会检查隐藏字段并相应更改位置

【讨论】:

  • 我认为,如果刷新页面会导致用户返回 main 页面并发出严峻的警报,这将导致非常糟糕的用户体验。用户应该被允许重新加载页面并且应用程序应该只是工作。但是,在某些情况下这是不可能的,告诉用户不要采取这些行动可能是最好的做法,但肯定不是每个 SPA。
  • @musically_ut 它的意思是一种玩笑——当然它非常依赖于上下文。但将其注释掉。
  • 好的,所以如果我理解得很好,没有“简单”的方式来处理刷新...我必须捕获未加载角度并强制重新加载主视图然后重定向到页面要重新加载。不是那么容易而且有点棘手。希望 Angular 具有这样的嵌入式功能,但我理解“用户不应该刷新”,但如果是这种情况,应用程序不会失败!
  • @G_A 问题是点击reload 会清除当前选项卡中的所有状态。它与角度本身无关。这就是浏览器中的 JavaScript 应该如何工作的。顺便提一句。我的建议可能是最基本的。您可以将应用程序的状态存储在 cookie 或其他永久存储(使用 HTML5)中,因此您可以以某种方式为重新加载后重新创建应用程序状态做好准备。但在大多数情况下,这可能不值得去做。
  • 我想要的第一件事是应用程序不会失败。所以我认为当检测到这不是从角度调用时重定向到“主”视图。没关系,当前状态暂时被刷新,作为第一步,这是一个非常合适的方法。
【解决方案2】:

在刷新 Angular 应用程序时避免丢失内容的最简单、最优雅的方法是使用 $cookies 服务将您需要的任何值存储在 cookie 中。这是一个例子。希望这会有所帮助。

"use strict";
angular.module('myApp').factory('SessionSrv', [ '$cookies', function($cookies){

    var _myString = $cookies.get('myString'); // e.g. "foo"
    var _myObject = $cookies.getObject('myObject'); // e.g. {foo: "bar"}

    return {

        setMyString: function(myString){
            _myString = myString;
            $cookies.put('myString', _myString);
        },

        getMyString: function(){
            return _myString;
        },

        setMyObject: function(myObject){
            _myObject = myObject;
            $cookies.putObject('myObject', _myObject);
        },

        getMyObject: function(){
            return _myObject;
        },

    };
}]);

【讨论】:

    【解决方案3】:

    最终实现了artur提出的解决方案:

    <script>
      if (typeof angular == 'undefined')
         window.location.replace("/main_url");
    </script>
    

    【讨论】:

    • 如果您只想说他的回答解决了您的问题,那么您为什么不能接受他的回答?
    • 因为有一点不同,而且他的解决方案没有按原样工作。
    猜你喜欢
    • 2017-11-27
    • 1970-01-01
    • 2012-12-22
    • 1970-01-01
    • 2021-10-05
    • 2011-05-13
    • 2011-12-03
    • 1970-01-01
    相关资源
    最近更新 更多