2014-05-25 157 views
3

我正在使用Restangular使用MEAN堆棧創建一個簡單的API。AngularJS - 模板無法正常工作

這裏是我的代碼:

的index.html

<!DOCTYPE html> 

<html data-ng-app="scotchTodo"> 
<head> 
    <!-- META --> 
    <meta charset="utf-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1"><!-- Optimize mobile viewport --> 

    <title>Node/Angular Todo App</title> 

    <!-- SCROLLS --> 
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css"><!-- load bootstrap --> 
    <style> 
     html{ 
      overflow-y:scroll; 
     } 
     body{ 
      padding-top:50px; 
     } 
    </style>  

    <!-- SPELLS --> 
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 

    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script> 
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular-route.min.js"></script> 

    <script src="//cdnjs.cloudflare.com/ajax/libs/restangular/1.4.0/restangular.min.js"></script> 
    <script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script> 

    <script src="app.js"></script> 
</head> 
<body> 
    <div data-ng-view> 

    </div> 
</body> 
</html> 

app.js

var scotchTodo = angular.module('scotchTodo', ['restangular','ngRoute']); 

//config 
scotchTodo.config(['$routeProvider','$locationProvider', function($routeProvider, $locationProvider) { 

    $routeProvider 
    .when('/',{ 
     templateUrl: 'list.html', 
     controller: 'ListController' 
    }) 
    .when('api/todos/:todo_id',{ 
     templateUrl: 'edit.html', 
     controller: 'EditController' 
    }); 

    $locationProvider.html5Mode(true); 

}]); 


//controllers 
scotchTodo.controller('ListController', ['$scope', 'Restangular', 
    function($scope, Restangular) { 

     //GET ALL 
     var baseTodo = Restangular.all('api/todos'); 
     baseTodo.getList().then(function(todos) { 
      $scope.todos = todos; 
     }); 

     //POST -> Save new 
     $scope.save = function() { 
      var baseTodo = Restangular.all('api/todos'); 
      var newTodo = {'text': $scope.text}; 
      baseTodo.post(newTodo).then(function(todos) { 
       $scope.todos = todos; 
       $scope.text = ''; 
      }); 
     }; 

     //DELETE 
     $scope.delete = function(id) { 
      var baseTodo = Restangular.one('api/todos', id); 
      baseTodo.remove().then(function(todos) { 
       $scope.todos = todos; 
      }); 
     }; 

    }]); 

scotchTodo.controller('EditController', ['$scope', 'Restangular','$routeParams', 
    function($scope, Restangular, $routeParams) { 

     var baseTodo = Restangular.one('api/todos', id); 

     baseTodo.getList().then(function(todo) { 
      $scope.todo = todo[0]; 
      window.test = "dev"; 
     }); 

     //PUT -> Edit 
     $scope.update = function(id){ 
      var baseTodo = Restangular.one('api/todos', id); 
      baseTodo.text = "Edited"; 
      baseTodo.put().then(function(todos) { 
       $scope.todos = todos; 
      }); 
     }; 

    }]); 

list.html

<div> 
    <div data-ng-repeat="todo in todos"> 
     {{todo.text}}<a href="api/todos/{{todo._id}}">Edit</a><button data-ng-click="delete(todo._id)">X</button> 
    </div> 
    <input type="text" data-ng-model="text"/> 
    <button data-ng-click="save()">Add</button> 
</div> 

edit.html

<div> 
    <input type="text" data-ng-model="text" value="{{todo.text}}" /> 
    <button data-ng-click="update(todo._id)">Save</button> 
</div> 

server.js

// setup ======================== 
var express = require('express'); 
var app = express(); 
var mongoose = require('mongoose'); 
var bodyParser = require('body-parser'); 

//configuration ================= 
mongoose.connect('mongodb://127.0.0.1:27017/sl', function(err, db) { 
    if (!err) { 
     console.log("We are connected to " + db); 
    } 
}); 

app.use(express.static(__dirname + '/public')); 
app.use(bodyParser()); 

// application ------------------------------------------------------------- 
app.get('/', function(req, res) { 
    res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end) 
}); 

//listen ======================== 
app.listen(8080); 
console.log('App started on the port 8080'); 

//define model ================== 
var Todo = mongoose.model('Todo', { 
    text: String 
}); 

// routes ====================================================================== 

// api --------------------------------------------------------------------- 

//get one todo 
app.get('/api/todos/:todo_id', function(req, res) { 

    // use mongoose to get all todos in the database 
    Todo.find({ 
     _id: req.params.todo_id 
    },function(err, todos) { 

     // if there is an error retrieving, send the error. nothing after res.send(err) will execute 
     if (err){ 
      res.send(err); 
     } 

     res.json(todos); // return all todos in JSON format 
    }); 
}); 

// get all todos 
app.get('/api/todos', function(req, res) { 

    // use mongoose to get all todos in the database 
    Todo.find(function(err, todos) { 

     // if there is an error retrieving, send the error. nothing after res.send(err) will execute 
     if (err){ 
      res.send(err); 
     } 

     res.json(todos); // return all todos in JSON format 
    }); 
}); 

// create todo and send back all todos after creation 
app.post('/api/todos', function(req, res) { 

    // create a todo, information comes from AJAX request from Angular 
    Todo.create({ 
     text: req.body.text, 
     done: false 
    }, function(err, todo) { 
     if (err){ 
      res.send(err); 
     } 

     // get and return all the todos after you create another 
     Todo.find(function(err, todos) { 
      if (err) 
       res.send(err); 
      res.json(todos); 
     }); 
    }); 

}); 

// update todo and send back all todos after creation 
app.put('/api/todos/:todo_id', function(req, res) { 

    // create a todo, information comes from AJAX request from Angular 
    Todo.update({ 
     _id: req.params.todo_id 
    }, { 
     text:req.body.text 
    }, function(err, todo) { 
     if (err){ 
      res.send(err); 
     } 

     // get and return all the todos after you create another 
     Todo.find(function(err, todos) { 
      if (err) 
       res.send(err); 
      res.json(todos); 
     }); 
    }); 

}); 


// delete a todo 
app.delete('/api/todos/:todo_id', function(req, res) { 
    Todo.remove({ 
     _id: req.params.todo_id 
    }, function(err, todo) { 
     if (err){ 
      res.send(err); 
     } 

     // get and return all the todos after you create another 
     Todo.find(function(err, todos) { 
      if (err){ 
       res.send(err); 
      } 
      res.json(todos); 
     }); 
    }); 
}); 

我的應用程序加載的第一頁完美的罰款。這是截圖。

list.html

但是當我點擊任何編輯鏈接的是應該載入edit.html模板。但它顯示了一個空白頁面,在控制檯中沒有錯誤。這是截圖。 edit.html

我無法弄清楚有什麼問題。請幫忙。請詢問是否需要其他任何代碼。我幾乎添加了我所做的一切。我知道這是討厭的,不建議,但我不知道我的代碼是什麼部分導致此問題。

編輯1:

我最遠的猜測是,edit.html的URL可能無法得到正確解決。但我不確定如何測試!任何幫助將appriciated。

編輯2:目錄結構

Directory Structure

SOLUTION:禮貌@ashu

的問題是此行的index.html

<script src="app.js"></script> 

它應該是:

<script src="/app.js"></script> 

但是,我不清楚爲什麼!無論哪種方式,頁面都包含app.js。真奇怪。

+1

它會工作,當你在'/'。在其他路線上,它將失敗並請求' /app.js'。您可以使用指定默認網址。 – ashu

回答

5

你有相同的路線角和快遞。

.when('api/todos/:todo_id',{ 
    templateUrl: 'edit.html', 
    controller: 'EditController' 
}); 

和快速

app.get('/api/todos/:todo_id', function(req, res) { 

因此,存在模糊性。您可以從角度網址中移除'api'部分。

.when('/todos/:todo_id', { 
    templateUrl: 'edit.html', 
    controller: 'EditController' 
}) 

而在服務器中,您可以添加一個處理所有非api url的catchall路由。爲了做到這一點,你可以在定義你的api路由後在底部移動你的app.get('/', function(req,res) {..})調用。

// < Define APi Routes here > 

//catch all route for serving the html template 
app.get('/*', function(req, res) { 
     res.sendfile('./public/index.html') 
}); 

此外,在app.js EditController,你忘了初始化ID的價值。

var id = $routeParams.todo_id; 
+0

未捕獲的SyntaxError:意外的令牌<-------------- app.js:1 – aBhijit

+0

可以列出更改嗎?你的部分在哪裏? (在公共目錄內?) – ashu

+0

^而你的app.js位於哪裏?它應該根據您的靜態中間件駐留在公共目錄內。 – ashu