【问题标题】:angular controller needing refresh to pickup new data in a factory promise角度控制器需要刷新以在工厂承诺中获取新数据
【发布时间】:2014-09-12 16:58:23
【问题描述】:

我有一个非常标准的应用程序,它将显示来自远程 JSON 提要的新闻项目。所以基本上我决定轮询远程服务器并将 JSON 存储在 localStorage 中(以启用离线使用)。目前,我有一个手册页/视图,我必须单击以更新 localStorage ,这工作正常。

问题是,在我使用我的临时手动更新页面后,我转到新闻页面/视图并且它没有更新。要查看当前的 JSON 内容,我必须点击刷新(同时仍在浏览器中开发。)

我对 Angular 完全陌生,并试图自己找到解决方案 - $watch 或 reload: true 似乎被建议作为修复,但我无法让它们在我的情况下工作。

路线

  .state('tab.news', {
      url: '/news',
      reload: true,
      views: {
        'news-tab': {
          templateUrl: 'templates/news_home.html',
          controller: 'newsCtrl'
        }
      }
    })

工厂

angular.module('schoolApp.services', [])

    .factory('newsService', function($q) {

        var newsHeadlines =localStorage.getItem('newsHeadlines') || '{"status":"READFAIL"}'; // get news as a JSON string. if newsHeadlines not found return a JSON string with fail status
        var newsHeadlinesObj = JSON.parse(newsHeadlines);// convert to an object 

        console.log("factory newsService ran");
        return {
            findAll: function() {
                var deferred = $q.defer();
                deferred.resolve(newsHeadlinesObj);
                return deferred.promise; // or reject(reason) to throw an error in the controller https://docs.angularjs.org/api/ng/service/$q
            },

            findById: function(newsId) {
                var deferred = $q.defer();
                var newsItem = newsHeadlinesObj[newsId];
                deferred.resolve(newsItem);
                return deferred.promise;
            }
          }   
    });

控制器

schoolApp.controller('newsCtrl', function($scope, newsService) {
  console.log ( 'newsCtrl ran' );

    newsService.findAll().then(function (newsHeadlinesObj) {
            $scope.newsHeadlinesObj = newsHeadlinesObj;
         }, function(error){
          console.log(error)
         });

})

看着我的控制台,我第一次阅读新闻时,工厂然后控制器运行,但如果我去拉更多数据,然后去破解新闻,只有控制器运行,除非我刷新,然后都运行再次。

我不需要新闻视图来更新“实时”,而仍然在它上面(但如果这可以轻松完成就更好了) - 只是为了在您在应用程序的其他地方返回新闻时获取新数据.

谢谢。

【问题讨论】:

    标签: angularjs cordova


    【解决方案1】:

    工厂返回单例并且只运行一次。对象newsService 由角度缓存。 newsHeadlinesnewsHeadlinesObj 的 var 声明只会运行一次;这意味着您的承诺返回方法将始终使用与您的工厂首次实例化时检索到的相同数据来解决承诺。您应该将它们放在一个函数中,并从单例对象的 find 方法中调用它。

    .factory('newsService', function($q) {
    
        function getHeadlines() {
            var newsHeadlines = localStorage.getItem('newsHeadlines') || '{"status":"READFAIL"}'; // get news as a JSON string. if newsHeadlines not found return a JSON string with fail
            return JSON.parse(newsHeadlines);// convert to an object
        }
    
        return {
            findAll: function() {
                var headlines = getHeadlines();
                var deferred = $q.defer();
                deferred.resolve(headlines);
                return deferred.promise; // or reject(reason) to throw an error in the controller https://docs.angularjs.org/api/ng/service/$q
            },
    
            findById: function(newsId) {
                var headlines = getHeadlines();
                var deferred = $q.defer();
                var newsItem = headlines[newsId];
                deferred.resolve(newsItem);
                return deferred.promise;
            }
          }   
    });
    

    PS - 我相信你知道并且计划稍后做一些不同的事情,但以防万一你不这样做:在这里使用承诺是没有意义的,你不需要在这里$q。您可以简单地返回数据而不是返回承诺。

    【讨论】:

    • 亚历克斯 - 非常感谢!完美运行。为什么你的函数按原样返回,为什么不自己返回 newsHeadlinesObj?
    • 只是一个疏忽。出于某种原因,我认为您在 promise 方法中使用了这两个变量。您确实可以自己返回 newsHeadlinesObj :)
    • 哦,不,我不知道。为什么它毫无意义(使用承诺)?因为从本地存储读取速度很快?
    • 因为您没有异步执行任何操作。您说您对服务器的异步调用是作为对服务器的轮询发生的,然后在返回时更新 localStorage。在你的工厂中访问 localStorage 是一个纯粹的同步操作,这就是为什么你可以直接将它分配给一个变量而不是传入一个回调函数。
    • 谢谢。我真的只是从我找到的例子中复制了一些东西。感谢您的解释!
    【解决方案2】:

    我在没有承诺的情况下解决了这个问题,我只是在工厂中使用了 $rootScope 并在控制器中使用了 $scope.$on ;当我更改工厂时,我使用 $rootScope.$broadcast 告诉控制器我更改了它。

    .factory('dataFactory', ['$http', '$rootScope', function ($http, $rootScope) {
        var dataFactory = {
            stock: null,
            getStock: getStock
        }
    
        function getStock() {
            $http.get("/api/itemfarmacia/").then(function success(res) {
                dataFactory.stock = res.data;
                $rootScope.$broadcast('changingStock'); //Ones who listen this will see it
            }, function error(err) {
                console.log("Bad request");
            })
        }
    
        return dataFactory;
    }])
    

    在控制器中

    .controller('atencion', ["$scope", "$state", "dataFactory", function ($scope, $state, dataFactory) {
        $scope.stock = dataFactory.stock; //At first is null
        dataFactory.getStock(); //wherever you execute this, $scope.stock will change
    
        $scope.$on('changingStock', function () {//Listening
            $scope.stock = dataFactory.stock; //Updating $scope
        })
    }])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-16
      • 2013-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多