2013-02-28 36 views
0

我有2个列表在我的应用程序和用户应该拖放项目从一个列表到另一个。
当用户从其中一个列表中删除一个元素到另一个列表时,必须向服务器端代码发出请求以更新数据库中的字段(SelectedForDiscussion)。
这是在我的控制器的代码:AngularJs 2承诺内一个手表第二个从来没有工作

$scope.$watch("questionsDiscuss", function (value) { 
    var question = $.Enumerable.From($scope.questionsDiscuss).Where(function (item) { return !item.SelectedForDiscussion }).FirstOrDefault() 
    if (question != undefined) { 

     questionSelectionService.UpdateQuestionSelectionStatus(question.Id, true) 
     .then(function (output) { 

      var question = $.Enumerable.From($scope.questionsDiscuss) 
           .Where(function (item) { return item.Id == output.data.questionId }) 
           .FirstOrDefault(); 
      var index = $.Enumerable.From($scope.questionsDiscuss).IndexOf(question); 

      if (question != undefined) 
       if (output.data.result != "success") { 
        $scope.questionsDiscuss.splice(index, 1); 
        $scope.questionsReceived.splice(0, 0, question); 
       } 
       else { 
        question.SelectedForDiscussion = true; 
        $scope.questionsDiscuss[index] = question; 
       } 
     }); 
    } 
    else { 
     var question = $.Enumerable.From($scope.questionsReceived).Where(function (item) { return item.SelectedForDiscussion }).FirstOrDefault(); 
     if (question != undefined) { 
      questionSelectionService.UpdateQuestionSelectionStatus(question.Id, false) 
      .then(function (output) { 
       var question = $.Enumerable.From($scope.questionsReceived) 
           .Where(function (item) { return item.Id == output.data.questionId }) 
           .FirstOrDefault(); 
       var index = $.Enumerable.From($scope.questionsReceived).IndexOf(question); 

       if (question != undefined) 
        if (output.data.result != "success") { 
         $scope.questionsReceived.splice(index, 1); 
         $scope.questionsDiscuss.splice(0, 0, question); 
        } 
        else { 
         question.SelectedForDiscussion = false; 
         $scope.questionsReceived[index] = question; 
        } 
      }); 
     } 

    } 

}, true); 

我有4 JavaScript的断点置于内萤火虫下列行:其中
2在下面的行:

if (question != undefined) { 

一个工作在:

var question = $.Enumerable.From($scope.questionsDiscuss) 
    .Where(function (item) { 
     return item.Id == output.data.questionId 
    }) 
    .FirstOrDefault(); 

,另一个在:

var question = $.Enumerable.From($scope.questionsReceived) 
    .Where(function (item) { 
     return item.Id == output.data.questionId 
    }) 
    .FirstOrDefault(); 

会出现以下情况:

断点在:

if (question != undefined) { 

总是到达。

断点在

var question = $.Enumerable.From($scope.questionsDiscuss) 
    .Where(function (item) { 
     return item.Id == output.data.questionId 
    }) 
    .FirstOrDefault(); 

也达到了。
另一个永远不会到达。
两个响应均正常(响应码200)。
一切都应该完美地工作,但第二个承诺中的then子句永远不会达到。
谁能告诉我我做错了什么?
服务器端应用程序是用C#编写的ASP.NET MVC应用程序。

编辑1: 我想出了为什么会发生这种情况,我有一个解决它的方法。我对一个实际的解决方案感兴趣。
问题是,当第二次调用$ http时,angularjs会抛出一个错误,然后吞下它。错误是:

消化alredy正在进行

我想这是因为在我的指导我有这样的代码:

dndfunc = function (scope, element, attrs) { 

    // contains the args for this component 
    var args = attrs.dndBetweenList.split(','); 
    // contains the args for the target 
    var targetArgs = $('#' + args[1]).attr('dnd-between-list').split(','); 

    // variables used for dnd 
    var toUpdate; 
    var target; 
    var startIndex = -1; 

    // watch the model, so we always know what element 
    // is at a specific position 
    scope.$watch(args[0], function (value) { 
     toUpdate = value; 
    }, true); 

    // also watch for changes in the target list 
    scope.$watch(targetArgs[0], function (value) { 
     target = value; 
    }, true); 

    // use jquery to make the element sortable (dnd). This is called 
    // when the element is rendered 
    $(element[0]).sortable({ 
     items: 'div', 
     start: function (event, ui) { 
      // on start we define where the item is dragged from 
      startIndex = ($(ui.item).index()); 
     }, 
     stop: function (event, ui) { 
      var newParent = ui.item[0].parentNode.id; 

      // on stop we determine the new index of the 
      // item and store it there 
      var newIndex = ($(ui.item).index()); 
      var toMove = toUpdate[startIndex]; 

      // we need to remove him from the configured model 
      toUpdate.splice(startIndex, 1); 

      if (newParent == args[1]) { 
       // and add it to the linked list 
       target.splice(newIndex, 0, toMove); 
      } else { 
       toUpdate.splice(newIndex, 0, toMove); 
      } 

      // we move items in the array, if we want 
      // to trigger an update in angular use $apply() 
      // since we're outside angulars lifecycle 
      scope.$apply(targetArgs[0]); 
      scope.$apply(args[0]); 
     }, 
     connectWith: '#' + args[1] 
    }) 
} 

而且有2个呼叫在年底申请这触发了我认为的一个新的摘要周期。
无论如何,我固定它通过添加调用之前此调用申请:

  if (scope.updateLists != undefined) 
       scope.updateLists(); 

,避开手表的所有代码到updateLists功能。

而且因为人们所提到的服务具有的东西,用它做我粘贴在它的相关代码:

GetQuestionsReceived: function (eid, criteria, page, rows) { 

    var promise = this.GetQuestionsReceivedInternal(eid,criteria, page, rows).then(function (response) { 
     // The return value gets picked up by the then in the controller. 
     return response; 
    }); 
    // Return the promise to the controller 
    return promise; 
}, 

GetQuestionsReceivedInternal: function (eid, criteria, page, rows) { 

    return $http({ method: 'GET', 
     url: '../QuestionManagement/GetQuestions?eventId='+eid+'&page=1&rows=5&'+serialize(criteria) 
    }). 
     success(function (data, status, headers, config) { 
      // this callback will be called asynchronously 
      // when the response is available 
      results = data; 
     }). 
     error(function (data, status, headers, config) { 
      // called asynchronously if an error occurs 
      // or server returns response with an error status. 
      if (window.console && console.log) { 
       console.log("Could not obtain questions received. Error:" + data + "Status:" + status + "Headers:" + headers + "Config:" + config); 
      } 
     }); 
}, 

    GetQuestionsDiscuss: function (eid,criteria, page, rows) { 

    var promise = this.GetQuestionsDiscussInternal(eid,criteria, page, rows).then(function (response) { 
     // The return value gets picked up by the then in the controller. 
     return response; 
    }); 
    // Return the promise to the controller 
    return promise; 
}, 

GetQuestionsDiscussInternal: function (eid,criteria, page, rows) { 

    return $http({ method: 'GET', 
     url: '../QuestionManagement/GetQuestions?eventId=' + eid + '&page=1&rows=5&' + serialize(criteria) 
    }). 
     success(function (data, status, headers, config) { 
      // this callback will be called asynchronously 
      // when the response is available 
      response = data; 
     }). 
     error(function (data, status, headers, config) { 
      // called asynchronously if an error occurs 
      // or server returns response with an error status. 
      if (window.console && console.log) { 
       console.log("Could not obtain questions received. Error:" + data + "Status:" + status + "Headers:" + headers + "Config:" + config); 
      } 
     }); 

}, 
+0

我们可以看到返回承诺的服务吗?你在延期对象上调用resolve()吗? – 2013-02-28 21:24:04

+0

两个建议; (1)'var index = ...;'开始的行可以,也许应该在它们各自的'if(question!= undefined){...}'块中移动; (2)你确定'if(question!= undefined)'是正确的测试吗?如果(!问题)'? – 2013-02-28 22:58:10

+0

对不起,应该是这样的:“如果(问题)'如何? – 2013-02-28 23:43:16

回答

0

你有两个代码非常相似的块,这可以推广,并放置在一个函数包装器,留下一个非常简单的调用函数。

如果你能把所有东西都弄成这种形式,那么我认为你会发现它更容易调试。

这里是一个试图这样做:

function updateSelectionStatus(qA, qB, bool) { 
    var en = $.Enumerable.From(qA); 
    var question = en.Where(function (item) { 
     return bool ? !item.SelectedForDiscussion : item.SelectedForDiscussion; 
    }).FirstOrDefault(); 
    if(question) { 
     questionSelectionService.UpdateQuestionSelectionStatus(question.Id, bool).then(function (output) { 
      if (output.data.result == "success") { 
       question.SelectedForDiscussion = bool; 
      } 
      else { 
       qA.splice(en.IndexOf(question), 1); 
       qB.unshift(question); 
      } 
     }); 
    } 
    return question; 
} 

$scope.$watch("questionsDiscuss", function (value) { 
    if (!updateSelectionStatus($scope.questionsDiscuss, $scope.questionsReceived, true) { 
     updateSelectionStatus($scope.questionsReceived, $scope.questionsDiscuss, false); 
    } 
}, true); 

我可能已经做了一些错误的假设和简化太多(如:清洗内$.Enumerable.From,这似乎重新选择为外同样的问题),所以你可能需要重写我的代码。

我在这里提倡一个原则,而不是提供解决方案。

相关问题