【问题标题】:Accessing factory properties in AngularJS + Chrome Apps APIs在 AngularJS + Chrome Apps API 中访问工厂属性
【发布时间】:2014-08-24 05:55:39
【问题描述】:

我正在尝试使用 AngularJS 构建一个 Chrome 应用程序,我需要的一项功能是通过 chrome.system.network.getNetworkInterfaces 监视可用的网络接口。目前,我正在尝试将这些数据存储在工厂中并将其注入视图控制器:

(尽量减少)

工厂:

exampleApp.factory('exampleFactory', ['$http', function ($http) {
    var service = {};
    service.network_interfaces = 'Detecting network connections...';

    chrome.system.network.getNetworkInterfaces(function(interfaces){
      service.network_interfaces = interfaces;
    })

    // This outputs the expected array containing interface data
    // in service.network_interfaces
    console.log(service)

    return service;
}]);

控制器:

exampleApp.controller('MainCtrl', ['$scope', '$http', 'exampleFactory', function($scope, $http, exampleFactory) {
    // This outputs the expected array in network_interfaces, identical
    // to the console output within the factory
    console.log(exampleFactory)

    // But then this outputs the initial 'Detecting network connections...'
    // string set in the factory
    console.log(exampleFactory.network_interfaces)

    // And {{network_interfaces}} and {{factory_state}} in the view keep
    // 'Detecting network connections...' as the value for network_interfaces
    // permanently
    $scope.factory_state = exampleFactory;
    $scope.network_interfaces = exampleFactory.network_interfaces;
}]);

所以:

  1. 工厂似乎返回了一个好的service 对象,但我不确定为什么exampleFactoryexampleFactory.network_interfaces 在控制器和工厂之间会有不同的状态,尤其是在控制器内部(无论他们被调用的顺序如何)。
  2. 我已经尝试了很多不同的解决方案,假设这是一个异步问题,但我认为getNetworkInterfaces 方法不会有明显的延迟,如果有的话,一切都为 Angular 正确设置返回数据后更新 {{network_interfaces}}{{factory_state}} 视图绑定。
  3. 我还尝试在工厂中使用$rootScope.$apply 包装各种功能,作为在黑暗中拍摄,但结果与上述相同。

我已经搜索了很多东西,以发现我显然错过的任何概念,但我认为我忽略了一些基本的东西。如何将 getNetworkInterfaces() 数据以有用的状态输入到我的控制器中?

【问题讨论】:

    标签: javascript angularjs dependency-injection google-chrome-app


    【解决方案1】:

    您在 #2 中的假设是问题所在。在调用异步方法和调用其回调之间总是会发生 JavaScript 事件循环。如果没有,各种事情都会在调用该方法的客户端中巧妙地中断。这意味着您在 Angular 开发中遇到了一个常见问题:您不会收到更改的通知,因为更改不是在 Angular 的摘要周期的上下文中发生的。

    要解决这个问题:尝试设置一个手表,然后在 getNetworkInterfaces() 回调中调用 $scope.apply()。 apply() 保证在摘要周期之外发生,因此您不应收到 apply-in-apply 错误。

    或者,在回调完成后给自己发一条消息。如果你是“如果你使用 apply(),你的代码就坏了”思想流派的学生,这会更好。

    最后,考虑在回调之后调用的 Promise。这不太适合您设置代码的方式。

    (另外,为什么要在工厂调用异步方法?)

    【讨论】:

    • 免责声明:和许多人一样,我发现 AngularJS 更改检测令人困惑,尤其是在与 Chrome 平台中的异步方法混合时。我可能给了你不好的建议。
    • (另外,为什么要在工厂调用异步方法?) 哇哦,为什么。我只用 Angular 做过简单的项目,所以我很不恰当地坚持“将共享数据/状态保持在控制器之外”的口号。我已将工厂中的getNetworkInterfaces 方法保留为service.network_interfaces,但将它的调用移到了控制器中,它现在可以正常工作了。
    • 我把 console.log('this is a hack/pause');在控制器返回之前的控制器中,Chrome 开始显示我工厂的数据。我本可以在这种怪事上花上几天的时间。谢谢。
    【解决方案2】:

    尝试查看 network_interfaces 以了解何时修改

    exampleApp.controller('MainCtrl', ['$scope', '$http', 'exampleFactory', function($scope, $http, exampleFactory) {
        // This outputs the expected array in network_interfaces, identical
        // to the console output within the factory
        console.log(exampleFactory)
    
        // But then this outputs the initial 'Detecting network connections...'
        // string set in the factory
        console.log(exampleFactory.network_interfaces)
    
        // And {{network_interfaces}} and {{factory_state}} in the view keep
        // 'Detecting network connections...' as the value for network_interfaces
        // permanently
        $scope.factory_state = exampleFactory;
        $scope.network_interfaces = exampleFactory.network_interfaces;
    
        $scope.$watch('factory_state.network_interfaces', function() {
           console.log($scope.factory_state)
       });
    }]);
    

    【讨论】:

    • 不幸的是,它仍然显示相同的奇怪行为:$scope.$watch('factory_state.network_interfaces', function() { console.log(exampleFactory) console.log(exampleFactory.network_interfaces) }); 第一个控制台输出在 network_interfaces 中有预期的数据,第二个控制台输出仍然有原始字符串。
    • 那行不通,因为 Chrome 回调不会触发 Angular 在其摘要周期中的更改检测。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-21
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 2018-06-12
    相关资源
    最近更新 更多