【问题标题】:Make data from factory http.get accessible to entire controller AngularJS使来自工厂 http.get 的数据可供整个控制器 AngularJS 访问
【发布时间】:2016-06-10 17:05:06
【问题描述】:

我正在尝试授予对包含我的项目配置信息的 json 文件的访问权限(例如版本号、项目名称、主要联系人等)我创建了一个使用 http.get 检索 json 文件的工厂,我可以然后将该数据拉入我的控制器,但我无法从控制器中的任何位置访问它。

我没有写工厂,我发现它是对另一个人的问题的回答,它几乎完全被复制,所以如果它不是完成我想要做的事情的正确方法,请纠正我。

这里是工厂:

app.factory('configFactory', ["$http", function($http) {

    var configFactory = {
        async: function() {
            // $http returns a promise, which has a then function, which also returns a promise
            var promise = $http.get('assets/json/config.json').then(function(response) {
                // The then function here is an opportunity to modify the response
                console.log(response.data.config);
                // The return value gets picked up by the then in the controller.
                return response.data.config;
            });
            // Return the promise to the controller
            return promise;
        }
    };
    return configFactory;

}]);

这是我的控制器:

app.controller('footerController', ['$scope', '$rootScope', 'configFactory', function footerController($scope, $rootScope, configFactory) {
    var body = angular.element(window.document.body);
    $scope.onChange = function(state) {
        body.toggleClass('light');
    };
    configFactory.async().then(function(d) {
        $scope.data = d;
        // this console log prints out the data that I am trying to access
        console.log($scope.data);
    });
    // this one prints out undefined
    console.log($scope.data);
}]);

所以基本上我可以访问用于检索它的函数内的数据,但不能访问它之外的数据。我可以用 rootScope 解决这个问题,但我试图避免这种情况,因为我认为它是一个创可贴,而不是一个合适的解决方案。

任何帮助都会很棒,但这是我第一次使用 http.get 和 promises 以及所有这些东西,所以非常感谢详细的解释。

[EDIT 1] 配置文件中的变量需要在网络应用程序中进行操作,所以我不能使用常量。

【问题讨论】:

  • 您无法在then 之外获取数据,因为在请求完成之前首先调用了console.log。这就是异步代码的工作原理。
  • @estus 那么我能做些什么来解决它呢?我可以添加一个超时功能来提供一个短暂的延迟(比如 10 毫秒),但这看起来很老套。
  • then回调中做所有与configFactory有关的事情,就这么简单。

标签: angularjs json angularjs-scope http-get angularjs-factory


【解决方案1】:

不要将您的响应数据分配给范围变量,在您的工厂本身中创建一个属性,并在您的承诺得到解决时将响应分配给您的控制器中的此属性。这样您将在所有其他控制器中获得值。

我已经更新了你的工厂和控制器,如下所示

app.factory('configFactory', ["$http", function($http) {

    var configFactory = {
        async: function() {
            // $http returns a promise, which has a then function, which also returns a promise
            var promise = $http.get('assets/json/config.json').then(function(response) {
                // The then function here is an opportunity to modify the response
                console.log(response.data.config);
                // The return value gets picked up by the then in the controller.
                return response.data.config;
            });
            // Return the promise to the controller
            return promise;
        },
      config:'' // new proprety added
    };
    return configFactory;

}]);

    app.controller('footerController', ['$scope', '$rootScope', 'configFactory', function footerController($scope, $rootScope, configFactory) {
    var body = angular.element(window.document.body);
    $scope.onChange = function(state) {
        body.toggleClass('light');
    };
    configFactory.async().then(function(d) {
       // $scope.data = d;
         configFactory.config=d;
        // this console log prints out the data that I am trying to access
        console.log($scope.data);
    });
    // this one prints out undefined
    console.log($scope.data);
}]);

【讨论】:

  • 我对我的代码进行了更改,它运行了,但我仍然遇到同样的问题,最后一行的 console.log 调用返回 'undefined' 这似乎无法让我访问数据在函数之外。
  • 大多数情况下,您不会直接在控制器主体中编写任何逻辑,您很可能仅在某些功能中具有逻辑。因此,假设您想在其他功能中使用此配置,而不是在您分配它的功能中,您将得到它。您在当前代码中没有得到它的原因是因为您的 console.log 直接写在控制器的主体,并在承诺得到解决之前被执行。将此代码放在某个函数中,然后在某些事件(例如 ng-click 或其他事件)上调用此函数..您将获得数据并且不会未定义
【解决方案2】:

您是否考虑过使用角度常数? http://ilikekillnerds.com/2014/11/constants-values-global-variables-in-angularjs-the-right-way/ 您可以将它们用作可从任何控制器访问的全局变量,而无需将值分配给 rootScope

【讨论】:

  • 这可行,但我确实需要对变量进行更改访问。我将编辑问题以包含此内容。
猜你喜欢
  • 2014-05-02
  • 2018-11-05
  • 2014-11-19
  • 1970-01-01
  • 1970-01-01
  • 2015-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多