在AngularJS + Chrome Apps api中访问工厂属性

Accessing factory properties in AngularJS + Chrome Apps APIs

本文关键字:访问 工厂 属性 api Apps AngularJS Chrome      更新时间:2023-09-26

我正在尝试使用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()数据到我的控制器在一个有用的状态?

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

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

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

最后,考虑一个在回调之后调用的Promise。这与您设置代码的方式不太匹配。

(还有,为什么要在工厂中调用async方法?)

试着观察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)
   });
}]);