2012-11-14 174 views
1

我正在学习如何使用an example的解决方案,并将其应用于我的Todo脚本。AngularJS解决承诺

然后我意识到一个问题,那个例子只是告诉我如何解决GET调用,让我第一次访问这条路线时,我得到了待办事项列表。

但是,在相同的路由相同的页面我有一个添加按钮POST新的todo项目,也清除按钮删除完成的项目。

看着我的$scope.addTodo = function() {$scope.clearCompleted = function() {我想解决我的TodoList行动后再次。我怎样才能做到这一点?

这是我的代码。在我的代码中,最初的resolve: { todos: TodosListResl }正在工作,它达到了TodosListResl函数并产生了承诺。但是,当我想再次解析待办事项列表时,我不知道如何处理addTodoclearComplete

enter image description here

main.js

var todoApp = angular.module('TodoApp', ['ngResource', 'ui']); 
todoApp.value('restTodo', 'api/1/todo/:id'); 

todoApp.config(function ($locationProvider, $routeProvider) { 
    $routeProvider.when("/", { templateUrl: "Templates/_TodosList.html", 
     controller: TodosListCtrl, resolve: { todos: TodosListResl } }); 
    $routeProvider.otherwise({ redirectTo: '/' }); 
}); 

//copied from example, works great 
function TodoCtrl($scope, $rootScope, $location) { 
    $scope.alertMessage = "Welcome"; 
    $scope.alertClass = "alert-info hide"; 

    $rootScope.$on("$routeChangeStart", function (event, next, current) { 
     $scope.alertMessage = "Loading..."; 
     $scope.alertClass = "progress-striped active progress-warning alert-info"; 
    }); 
    $rootScope.$on("$routeChangeSuccess", function (event, current, previous) { 
     $scope.alertMessage = "OK"; 
     $scope.alertClass = "progress-success alert-success hide"; 

     $scope.newLocation = $location.path(); 
    }); 
    $rootScope.$on("$routeChangeError", 
     function (event, current, previous, rejection) { 
     alert("ROUTE CHANGE ERROR: " + rejection); 
     $scope.alertMessage = "Failed"; 
     $scope.alertClass = "progress-danger alert-error"; 
    }); 
} 
//also copied from example, works great. 
function TodosListResl($q, $route, $timeout, $resource, restTodo) { 
    var deferred = $q.defer(); 
    var successCb = function(resp) { 
     if(resp.responseStatus.errorCode) { 
      deferred.reject(resp.responseStatus.message); 
     } else { 
      deferred.resolve(resp); 
     } 
    }; 
    $resource(restTodo).get({}, successCb); 
    return deferred.promise; 
} 
//now, problem is here in addTodo and clearCompleted functions, 
//how do I call resolve to refresh my Todo List again? 
function TodosListCtrl($scope, $resource, restTodo, todos) { 
    $scope.src = $resource(restTodo); 
    $scope.todos = todos; 
    $scope.totalTodos = ($scope.todos.result) ? $scope.todos.result.length : 0; 

    $scope.addTodo = function() { 
     $scope.src.save({ order: $scope.neworder, 
          content: $scope.newcontent, 
          done: false }); 
         //successful callback, but how do I 'resolve' it? 
    }; 
    $scope.clearCompleted = function() { 
     var arr = []; 
     _.each($scope.todos.result, function(todo) { 
      if(todo.done) arr.push(todo.id); 
     }); 
     if (arr.length > 0) $scope.src.delete({ ids: arr }); 
     //successful callback, but how do I 'resolve' it? 
    }; 
} 

回答

3

我认为你缺少的resolve点。 resolve这一点就是“delay route change until data is loaded。对于你的情况,你已经在一条路线上,并且你想保持这条路线,但是你想在成功的回调中更新todos变量,在这种情况下,不想使用resolve,相反,只是做需要做的事情。例如

$scope.addTodo = function() { 
    $scope.src.save({ order: $scope.neworder, 
         content: $scope.newcontent, 
         done: false }, function() { 
     todos.push({ order: $scope.neworder, 
         content: $scope.newcontent, 
         done: false }); 
    }); 
        //successful callback, but how do I 'resolve' it? 
}; 

作为面点什么,我注意到你正在使用_最有可能从下划线库。你并不需要使用另一个库,因为Angular已经有$angular.forEach()

+0

谢谢你阅读我的长问题并给我宝贵的意见所以,这是不是说, Rred Promise在我的TodosListResl函数中没用?如果我直接执行$ resource.get(),那么它有什么区别?而不是有麻烦来构建延期承诺。既然Resolve已经在延期了?这就是我感到困惑的地方,这个例子的重点是如何使用解决方案和承诺? – Tom

+0

只有一条路线,您可能不需要解决/延期承诺。解释$ resource docs:调用$ resource方法(如get())立即返回一个空引用(对象或数组)。一旦服务器返回数据,该引用就会填充数据。这通常用于将资源分配给模型:空对象不导致渲染,然后一旦数据到达,模型/对象就会填充数据并自动更新视图。所以在大多数情况下,您不必为动作方法编写回调函数。 –

+0

如果你想延迟显示一个全新的视图(比如用ng-view)直到数据(成功地)从服务器到达,解析和承诺是有用的。通常情况下,您将使用此工具处理多条路线。如果你确实需要承诺,我建议你看看这个答案,它使用$ http而不是$ resource:http://stackoverflow.com/a/12360882/215945 –