为什么手表触发需要$ timeout

时间:2014-12-16 12:13:21

标签: javascript angularjs

我有一个监视元素高度的指令。该元素由使用工厂方法获取数据的控制器更新。除非我在该工厂有$timeout,否则我的手表永远不会更新。好奇!任何人都可以阐明原因吗?

我的控制器:

$scope.update = function () {
    apiService.getLinks(function (response) {
        $scope.links = response;
        // If I try $scope.$apply() here it says its already in progress, as you'd expect
    });
}

quickLinksServices.factory('quickLinksAPIService', function ($http, $timeout) {

    quickLinksAPI.getQuickLinks = function (success) {

        //without this the watch in the directive doesnt get triggered
        $timeout(function () { }, 100); 

        $http({
            method: 'JSON',
            url: '/devices/getquicklinkcounts'
        }).success(function (response) {
            quickLinksAPI.quicklinks = response;
            quickLinksAPI.saveQuickLinks();

            success(response);
        });
    }

我使用的指令是here

2 个答案:

答案 0 :(得分:3)

基本上angularjs在指定时间后提供$ timeout服务来触发函数调用,但是我知道不需要使用$ timeout,基本上人们有写这个的习惯我的意思是他们需要在指定的间隔后触发监视。但在许多情况下,$ apply可以解决问题。你需要的是$ apply()。供您参考,请查看this

还有很多次发生的事情是角度$ watch的执行速度比你预期的要快,所以它可能会发送不完整的更新或响应在这种情况下,$ timeout通过延迟$ watch起到重要作用。如果$ watch足够快,您可以清除$ timeout,这意味着$ timeout是显式触发$ watch的方式,其中$ apply可以自行完成。因此,$ timeout或$ apply的使用取决于您的要求。希望这能让你清楚。祝你好运。

答案 1 :(得分:0)

这是因为您没有以正确的方式使用$ http承诺。

以下代码未经过测试,但展示了如何解决您的问题。注意返回$ http。在这里,您将返回承诺并在代码中处理承诺。

$scope.update = function () {
  quickLinksServices.quickLinksAPI.getQuickLinks().then(function(data){
        $scope.links = data;
     }
    );
 };


quickLinksServices.factory('quickLinksAPIService', function ($http, $timeout) {
    quickLinksAPI.getQuickLinks = function (success) { return $http({
        method: 'JSON',
        url: '/devices/getquicklinkcounts'
    });
    });
}

如果由于设计决定而无法以这种方式工作,您仍然需要使用承诺($ q)。如果你想进一步了解promises here是stackoverflow上的一个好线程。