Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/479.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角度$scope$watch on service函数返回值_Javascript_Angularjs - Fatal编程技术网

Javascript 角度$scope$watch on service函数返回值

Javascript 角度$scope$watch on service函数返回值,javascript,angularjs,Javascript,Angularjs,我为我的websocket连接提供了一个服务,该服务在函数中返回实际状态,无论客户端是否实际连接。 我简化了我的代码,这些代码片段是我的问题的一个小例子: myApp.factory('Websocket', function() { //the status boolean whether connected or not var bool = true; //small mock for the status change setInterval(funct

我为我的websocket连接提供了一个服务,该服务在函数中返回实际状态,无论客户端是否实际连接。 我简化了我的代码,这些代码片段是我的问题的一个小例子:

myApp.factory('Websocket', function() {
    //the status boolean whether connected or not
    var bool = true;

    //small mock for the status change
    setInterval(function() {
        bool = !bool;
    }, 1000);

    //i've made the value of the status variable accessable in a function or the variable itself
    return {
        status: function() {
            return bool;   
        },
        var: bool
    }
});
现在,我尝试将状态值应用于控制器中的作用域:

myApp.controller('Ctrl', function(Websocket, $scope) {
   //method 1
   $scope.status = Websocket.status();

   //method 2
   $scope.$watch(function() {
     return Websocket.status();
   }, function(newVal) {
     $scope.status = newVal;
   });
});
…但这两种方法都不起作用,也不更新此html的$scope变量:

<div ng-app="myApp">
    <div ng-controller="Ctrl">
      method1: {{status}}
    </div>
</div>

方法1:{{status}}
这是一个密码笔:


谢谢你的帮助

问题是Angular监视的数据的任何“外部”更改都必须调用
scope.$apply()
,以便监视程序进行更新(这里的监视程序是
{{status}}
表达式中的UI)。在codepen中,解决方案很简单:使服务依赖于
$rootScope
并在interval函数中调用
$rootScope.$apply()

myApp.factory('Websocket', function($rootScope) {
    ...
    setInterval(function() {
        bool = !bool;
        $rootScope.$apply();
    }, 1000);
    ...
});

对于真正的服务也必须做类似的事情,关键概念是:(1)您必须调用
$apply()
,(2)无法访问特定的范围,只需使用
$rootScope

问题正如Nikos提到的:您正在摘要循环之外更改变量的值,所以angular没有跟随这些变化

使用
$scope.$apply
是一个选项,但在这种情况下,我更喜欢使用而不是
setInterval

myApp.factory('Websocket', function($interval) {
  var bool = true;
  $interval(function() {
    bool = !bool;
  }, 1000);

  return {
    status: function() {
        return bool;   
    },
    var: bool
  }
});

看到它工作。

谢谢你的帮助!谢谢你的帮助!我会选择$rootScope.$digest,而不是$apply,因为您所做的只是跳转一个try/catch语句以获得相同的结果。不是很贵,但是没有真正的理由这么做。