Странное поведение маршрутизации в Angular

перед обновлением

У меня есть настройка приложения Mean, где приложение Angular находится в пути «/dashboard». Домашняя страница приложения работает нормально. При перезагрузке приложения возвращается страница, на которой оно находилось. На самом деле, даже в маршрутах с маршрутами «/dashboard/anything/anything» приложение обновляется просто отлично. Но когда я обновляю страницу в маршрутах «/dashboard/anything», приложение angular не загружает приложение, и все, что у меня остается, это HTML-код представлений. Я пытался исправить это многими способами, но не могу найти правильного объяснения этому странному поведению.

При обновлении происходит следующее:

Страница, которую я оставил после обновления.

Маршрутизация в моем приложении выглядит следующим образом:

angular.module('dashboard', ['ngRoute'])
.config(function ($routeProvider, $locationProvider) {
    $routeProvider

    // route for the dashboard home page
        .when('/dashboard/login', {
            templateUrl: 'dashboard/login/index.html'
        })
        .when('/dashboard', {
            templateUrl: 'dashboard/home/index.html'
        })
        .when('/dashboard/events', {
            templateUrl: 'dashboard/events/index.html'
        })
        .when('/dashboard/events/create', {
            templateUrl: 'dashboard/events/create.html'
        })
        .when('/dashboard/events/report', {
            templateUrl: 'dashboard/events/reports.html'
        })

        .when('/dashboard/users', {
            templateUrl: 'dashboard/users/index.html'
        })
        .when('/dashboard/users/create', {
            templateUrl: 'dashboard/users/create.html'
        })
        .when('/dashboard/users/reports', {
            templateUrl: 'dashboard/users/reports.html'
        })

        .when('/dashboard/images', {
            templateUrl: 'dashboard/media/index.html'
        })
        .when('/dashboard/images/add', {
            templateUrl: 'dashboard/media/create.html'
        })
        .when('/dashboard/categories', {
            templateUrl: 'dashboard/categories/index.html'
        })
        .when('/dashboard/logout', {
            templateUrl: ''

        })
        .otherwise({
            redirectTo: 'dashboard'
        });
    $locationProvider.html5Mode(true);
})

И маршрутизация в узле выглядит следующим образом: -

router.get('/dashboard', function(req, res) {
  res.sendFile('/dashboard/index.html',{ root: path.join(__dirname,  '../public') });
});

router.get('/dashboard/*',function(req, res) {
  console.log("Here");
  res.sendFile('/dashboard/index.html',{ root: path.join(__dirname, '../public') });
});

Обновление: больше фрагментов кода. Я не упоминал ранее, что у меня есть два угловых приложения, настроенных на двух разных маршрутах. Первое приложение на корневом уровне работает как шарм, но у приложения на уровне /dashboard есть эта проблема.

APP.JS

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var router = express.Router();
var index = require('./routes/index');
var users = require('./routes/users');
var events = require('./routes/events');
var sponsors = require('./routes/sponsors');
var image = require('./routes/images');
var dashboard = require('./routes/dashboard');
var login=require('./routes/login.js');
var unless = require('express-unless');
// var router = express.Router();
var config = require('./config.js');
require('./database');
var jwt = require('jsonwebtoken');
var smsRoute=require('./routes/smsApi');
var sendSms=smsRoute.router;
var Models = require('./models/models');
var User = Models.user;
var app = express();
var mailer=require('./mailer/mailer.js');

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));


app.use('/', index);
app.use('/dashboard', dashboard);
app.use('/api/send',sendSms);
app.use('/api/login',login);
app.use('/api/mail',mailer);
app.use('/api/events', events);
app.use('/api/users', users);
app.use('/api/sponsors', sponsors);
app.use('/api/image', image);
app.use('*', index);

app.set('superSecret', config.secret);


// catch 404 and forward to error handler
app.use(function (req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function (err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});


module.exports = app;

ИНДЕКС.JS

var express = require('express');
var router = express.Router();
var path = require('path');
/* GET home page. */

router.get('/', function (req, res, next) {
    res.sendFile('/app/index.html', {
        root: path.join(__dirname, '../public')
    })
});


module.exports = router;

DASHBOARD.JS

var express = require('express');
var router = express.Router();
var path = require('path');

router.get('/*', function(req, res) {
    res.sendFile('/dashboard/index.html',{ root: path.join(__dirname, '../public') });
});


module.exports = router;

И многих маршрутов API.

var express = require('express');
var router = express.Router();
var Models = require('../models/models');
var Sponsor = Models.sponsor;



/*----------------Get All Users--------------*/
router.get('/',function(request,response) {

    Sponsor.find({},function(err,sponsors) {
        if(err) 
            return response.status(500).json({message : err.message});
        response.json({ sponsors : sponsors});
        response.end();

    });

});


 /*----------------Get User By Id--------------*/


router.get('/:id',function (request,response) {
    var id=request.params.id;

    Sponsor.find({_id:id},function(err,sponsor) {
        if (err)
            return response.status(500).json({message : err.message});
        response.status(200).json({sponsor:sponsor,message:"Sucess"});
        response.end();

    });
});

router.use(require('./tokenVerify.js'));

/*
 *
 *                                                     Start protected routes
 *-------------------------------------------------------------------------------------------------------------------
 *
 *                                             Route authentication using JSONWEBTOKEN.
 *
 */



/*----------------Create New User--------------*/
router.post('/', function (request, response) {
    var sponsor = request.body;
    Sponsor.create(sponsor,function(err,sponsor) {
        if(err) 
            return response.status(500).json({message : err.message});
        response.json({ sponsor : sponsors , message : "Success"});
        response.end();

    });
});



    /*----------------Update Existing User--------------*/


router.put('/:id', function (request, response) {
    var id = request.params.id;
    var sponsor  = request.body;
    if(sponsor && sponsor._id !== id) 
        return response.status(500).json({error : "The id's do not match.", message : "Failure"});
    sponsor["modifiedDate"]=Date();
    Sponsor.findByIdAndUpdate(id, user, { new : true }, function(err,user) {
        if(err) 
            return response.status(500).json({error : err.message, message : "User Not Found"});
        response.status(200).json({message : "Success"});
        response.end();

    });

});

 /*----------------Delete  Existing User--------------*/

router.delete("/:id",function(request,response) {
    var id = request.params.id;
    Sponsor.findOneAndRemove({_id:id},function(err) {
        if (err) 
          {  return response.status(500).json({error:err.message, message:"Can't Delete User"}); console.log("Error");}
        response.status(200).json({message:"Sucess"});       
        response.end();
    });
})




module.exports = router;

Я пытался максимально рефакторить код. Я абсолютно не знаю, что происходит не так. Сделал много поиска, но не могу найти ответы, которые мне нужны.


person Kumar Divya Rajat    schedule 12.03.2016    source источник
comment
Вы ставите angular и node на один и тот же путь?   -  person Mukul Medatwal    schedule 12.03.2016
comment
Нет. Angular и узел не находятся на одном пути.   -  person Kumar Divya Rajat    schedule 12.03.2016
comment
Уважаемый, ваш код выглядит таким запутанным, но я покажу вам, как это сделать правильно на примере. Следовательно, вы можете изменить его в соответствии с вашими потребностями.   -  person Amulya Kashyap    schedule 12.03.2016


Ответы (2)


Вы смешиваете реальные URL-адреса файлов (например, шаблоны) и псевдомаршруты для angular. Если это так, то при попытке angular загрузить файл шаблона, например dashboard/users/reports.html, экспресс-маршрут с подстановочными знаками /dashboard/* вместо этого возвращает файл /dashboard/index.html. Их безопаснее разделить так:

В узле:

router.use('/templates', express.static(path.join(__dirname, 'path/to/templates')));

router.get('/dashboard', function(req, res) {
  res.sendFile('/dashboard/index.html',{ root: path.join(__dirname,  '../public') });
});

router.get('/dashboard/*',function(req, res) {
  console.log("Here");
  res.sendFile('/dashboard/index.html',{ root: path.join(__dirname, '../public') });
});

В угловом:

.when('/dashboard/images', {
    templateUrl: '/templates/dashboard/media/index.html'
})
person Dima Fitiskin    schedule 12.03.2016

вот мой файл app.js:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var viewRoute = require('./routes/view'), //defining routes
    apiRoute = require('./routes/api'),

app.set('views', path.join(__dirname, 'views'));  //setting to HTML engine instead of EJS | JADE 
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', viewRoute);   //using middleware for routing
app.use('/api', apiRoute);

Посмотрите, у меня есть две вещи :

  1. Просмотр -- Отрисовка файлов HTML
  2. Api -- код для обработки запроса на получение/отправку из представлений (файлы HTML)

Теперь файл view.js

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index');
});

router.get('/home', function(req, res, next) {
  res.render('pages/home');
});

router.get('/login', function(req, res, next) {
  res.render('pages/login');
});


router.get('/about', function(req, res, next) {
  res.render('pages/about');
});

module.exports = router;

Теперь файл api.js:

var express = require('express');

module.exports = (function() {

    'use strict';

    var api = express.Router();

    api.get('/home', function(req, res, next) {
      console.log("A GET Request for Home Page\n");
    });


    api.get('/dashboard', function(req, res, next) {
      console.log("A GET Request for About Page\n");
    });

    api.get('/about', function(req, res, next) {
      console.log("A GET Request for About Page\n");
    });

return api;

})();

Теперь мой файл контроллера AngularJs для маршрутизации:

$routeProvider
        .when('/home', {
            templateUrl: '/home',
            controller: 'homeCtrl'
        })
        .when('/login', {
            resolve : {
                'check' : function ($location, $cookies){
                    if ($cookies.get('isAuthenticated') && $cookies.get('current_user')) {
                        $location.path('/dashboard');
                    }
                }
            },
            templateUrl: '/login',
            controller: 'loginCtrl'
        })
        .when('/dashboard', {
            resolve : {
                'check' : function ($location, $cookies){
                    if (!$cookies.get('isAuthenticated') || !$cookies.get('current_user')) {
                        $location.path('/login');
                    }
                }
            },
            templateUrl: '/dashboard',
            controller: 'dashboardCtrl'
        })
        .otherwise('/home');

Теперь вы увидите мои файлы контроллера, в которых только после входа в систему я настроил пользователей на посещение моих различных маршрутов, добавленных к панели управления и после:

myApp.controller('homeCtrl', function ($interval, $rootScope, $scope) {
    //Displaying HOME page
});

myApp.controller('loginCtrl', function ($scope) {
    //DISPLAYING LOGIN PAGE FOR LOGIN
    //YOUR LOGIN CODE GOES HERE AND AFTER THAT DO:
     $location.path('/dashboard/*'); //depending on you
});

smpApp.controller('aboutCtrl', function ($interval, $rootScope, $scope) {
    //DISPLAYING YOUR ABOUT US PAGE
});

УВЕДОМЛЕНИЕ Следующие вещи Keenly :

  1. Маршруты проверяются каждый раз. Значит они аутентифицированы.
  2. Различные файлы для просмотра HTML-файла и обработки запроса get/POST из этих файлов
  3. Контроллеры разные для каждого файла
  4. Использование $location.path для перехода или отправки пользователя на панель инструментов.

Спасибо и привет

person Amulya Kashyap    schedule 12.03.2016
comment
Привет. На самом деле это почти так же, как я сейчас настроил свое приложение. Единственная разница заключается в том, что на самом деле у меня есть два отдельных приложения Angular на двух маршрутах. У меня есть моя логика API, разграниченная в разных файлах. И мои маршруты аутентифицируются с помощью $rootScope.on('$routeChangeStart'). Но пока я сталкиваюсь с этой проблемой. Я не могу понять это. Другое угловое приложение, расположенное в корне, работает как обычно. Никаких проблем. Вместо того, чтобы публиковать фрагмент, я публикую больше кода выше. - person Kumar Divya Rajat; 13.03.2016