【问题标题】:Updating a controller scope through a service通过服务更新控制器范围
【发布时间】:2017-02-12 22:38:50
【问题描述】:

我的页面通过调用 AWS S3 存储桶中的 listObjects 函数来加载。这基本上是一个异步调用,它在 AWS S3 中获取一堆对象。

如果我将此调用放在控制器中,然后在异步调用返回并处理所有数据时执行 $scope.$apply() ,这会很好。

但是,每个页面基本上都必须对 S3 存储桶进行相同的调用以填充页面,所以我基本上将相同的代码粘贴到每个控制器上。

显而易见的做法是将此代码移动到服务中,但如何通过服务更新控制器中的范围?我不能在我的服务中执行 $scope.$apply()。

如何让调用该服务的控制器知道异步调用已完成处理并更新控制器中的 $scope 变量?

感谢您的帮助。

【问题讨论】:

    标签: angularjs amazon-web-services asynchronous promise


    【解决方案1】:

    我建议使用 Promises 和 Angular $q 服务。为此,只需创建一个返回 Promise 的服务函数。然后,您可以在 Controller 中等待此 Promise,如果它得到解决,您可以将响应分配给 Controller 的 $scope

    plunkr(查看开发工具)

    我创建了一个简单的演示:

    var app = angular.module('demo', []);
    
    app.controller('demoCtrl', function(demoService) {
    
      var self = this;
    
      self.init = init;
      self.list = {};
    
      init();
    
      function init () {
    
        console.log("call async Service Method");
        demoService.getListObjects()
          .then(function (list) {
            console.log("received", list);
            // Assign Response to the Scope
            self.list = list;
          });
      }
    });
    
    
    app.service('demoService', function($q) {
      var self = this;
    
      self.getListObjects = getListObjects;
    
      function getListObjects() {
        var deferred= $q.defer();
    
        // Simulate Async Action
        setTimeout(function () {
          var list = {};
          deferred.resolve(list);
        }, 1000);
    
        return deferred.promise;
      }
    });
    

    【讨论】:

    • 谢谢,我会试试这个,稍后再回来查看。
    【解决方案2】:

    您可以从 Service 方法返回一个对象数组,并在控制器调用方法中分配它。

    服务:

    angular
            .module('app')
            .service('servS3', servS3);
    
    function servS3()
    {
       var service = {
          gets3List = gets3List
       };
       return service;
    
      function gets3List(){
           //Write your logic and return array of s3 List
    
      };
    }
    

    控制器:

    $scope.s3ListObject = [];
    
    servS3.gets3List()
    .then(function(response){
      $scope.s3ListObject = response.data;
    });
    

    此外,如果可以进行缓存,请尝试在登录期间缓存此 S3Data(在 sessionStorage 上),而不是每次都加载数据,这可能会影响性能。

    【讨论】:

    • 如果我使用正确的路由,我不应该担心缓存吗?我认为 Angular 默认会缓存你的路由状态。
    • 我说的是数据缓存。如果来自 AWS S3 Bucket 的列表对象不会因页面而异,则仅调用该方法一次并将其存储在会话存储中。这将避免多次往返 AWS s3 存储桶的列表对象函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-15
    • 2014-11-27
    • 1970-01-01
    • 2015-04-30
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多