2013-02-24 11 views
6

Wyjaśnię problem tak szczegółowo, jak to możliwe.Express i AngularJS - strona internetowa zawiesza się przy próbie otwarcia strony głównej.

Próbuję użyć AngularJS z Expressem i mam problem. Chcę wyświetlać pliki HTML (bez użycia silnika szablonowego). Te pliki HTML będą miały dyrektywy AngularJS.
Jednak nie jestem w stanie wyświetlić samego prostego pliku HTML!

Struktura katalogu jest następujący:

Root 
---->public 
-------->js 
------------>app.js 
------------>controllers.js 
---->views 
-------->index.html 
-------->partials 
------------>test.html 
---->app.js 

Zawartość public/js/app.js jest:

angular.module('myApp', []). 
    config(['$routeProvider', function($routeProvider) { 
    $routeProvider.when('/', {templateUrl: 'partials/test.html', controller: IndexCtrl}); 
$routeProvider.otherwise({redirectTo: '/'}); 
}]); 

Zawartość public/js/controllers/js jest:

function IndexCtrl() { 
} 

Zawartość znacznika body w views/index.html jest:

<div ng-view></div> 

To wszystko. Oczekuje się, że angularjs zastąpi powyższy widok z test.html - views/partials/test.html którego zawartość to:

This is the test page! 

zamknięte wewnątrz znaczników akapitu. To jest to!

Wreszcie zawartość ROOT/app.js pliku to:

var express = require('express'); 

var app = module.exports = express(); 

// Configuration 

app.configure(function(){ 
    app.set('views', __dirname + '/views'); 
    app.engine('html', require('ejs').renderFile); 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(express.static(__dirname + '/public')); 
    app.use(app.router); 
}); 

app.configure('development', function(){ 
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
}); 

app.configure('production', function(){ 
    app.use(express.errorHandler()); 
}); 

// routes 

app.get('/', function(request, response) { 
    response.render('index.html'); 
}); 

// Start server 

app.listen(3000, function(){ 
    console.log("Express server listening on port %d in %s mode", this.address().port, app.settings.env); 
}); 

Teraz, kiedy robię $node app.js w folderze głównym, serwer uruchamia się bez błędu. Jeśli jednak przejdę do adresu localhost:3000 w przeglądarce, adres URL zmieni się na localhost:3000/#/, a strona zostanie zablokowana/zamarznięta. Nie mogę nawet sprawdzić logu konsoli w Chrome!
To jest problem, z którym mam do czynienia. Jakaś wskazówka na temat tego, co robię źle?

+0

jakie błędy są zgłaszane w konsoli przeglądarki? – charlietfl

+0

@charlietfl prawdopodobnie nic. Przeważnie gdy strona wydaje się być zamrożona, to dlatego, że odpowiedź się nie kończy. – Pickels

+0

'prawdopodobnie nic' ?? albo są zgłaszane błędy, albo nie są one – charlietfl

Odpowiedz

8

W końcu to wymyśliłem - po wielu intensywnych chwilach ciągnięcia za włosy !!
Powodem, dla którego strona zawiesza się tak dlatego (wyjaśnione krok po kroku):

  1. Użytkownik uruchamia localhost: 3000
  2. Ten żąda Server Express dla '/'
  3. Express, tynki index.html
  4. AngularJS wyświetli szablon "partials/test.html".
  5. Tutaj biorę szalone domysły - AngularJS wysłał żądanie HTTP dla strony "partials/test.html".
  6. Jednak można zauważyć, że aplikacja express lub raczej app.js nie ma programu obsługi dla tego żądania GET. Oznacza to, że brakuje następującego kodu:

    aplikacja.się ('podszablonów /: nazwa', funkcja (prośba response) {
    nazwa zmiennej = request.params.name;
    response.render ('partials /' + nazwa)
    });

wewnątrz app.js katalogu ROOT. Po dodaniu tego kodu strona wyświetla się zgodnie z oczekiwaniami.

+0

Innym (lepszym) rozwiązaniem jest umieszczenie twoich części w folderze 'public', aby były obsługiwane przez statyczne oprogramowanie pośredniczące bez potrzeby tworzenia dla nich określonej trasy i bez przechodzenia przez stos routera/aplikacji. Zwróć uwagę, że twój system będzie bardzo wolny, aby użytkownicy ładowali strony, ponieważ będą musieli pobrać stronę indeksu z ekspresu, załadować DOM i Angular, wykonać żądanie HTTP, aby uzyskać częściowe, wykonać JavaScript, aby wyrenderować stronę. Bardzo skomplikowane i powolne IMO. – jtblin

+0

@jtblin Myślę, że twoje rozwiązanie ma zastosowanie, gdy twoje szablony są publiczne ... W moich przypadkach są one ograniczone i można uzyskać do nich dostęp tylko z odpowiednimi uprawnieniami ... – callmekatootie

0

Spróbuj wykonać wzór w postaci this working fiddle. Kod przedstawiony poniżej. Możesz zamienić opcję szablonu na templateUrl i powinna nadal działać poprawnie.

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

app.config(['$routeProvider', function($routeProvider){ 
    $routeProvider.when('/', {template: '<p>Index page</p>', controller: 'IndexCtrl'}); 
    $routeProvider.otherwise({redirect:'/'}); 
}]); 

app.controller('IndexCtrl', function(){ 

}); 
+0

Chcę zachować plik 'app.config()' wewnątrz app.js i 'app.controller()' wewnątrz pliku controllers.js. Jednak w pliku controllers.js, jeśli używam zmiennej lokalnej, nie działa. Nie wiem, dlaczego – callmekatootie

Powiązane problemy