角度控制器需要刷新以在工厂承诺中获取新数据 [英] angular controller needing refresh to pickup new data in a factory promise

查看:80
本文介绍了角度控制器需要刷新以在工厂承诺中获取新数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a pretty standard app which will display news items from a remote JSON feed. So basically I have decided to poll the remote server and store the JSON in localStorage (to enable offline usage). For the moment, I have a manual page/view I must click on to update the localStorage , this works fine.

问题在于,使用临时的手动更新页面后,我转到新闻页面/视图,并且该页面未更新.要查看当前的JSON内容,我必须单击刷新"(同时仍在浏览器中进行开发.)

The problem is that after I use my temporary manual update page, I then go to the news page/view and it is not updated. To view the current JSON contents I must hit refresh (while still developing in the browser.)

我是Angular的新手,并尝试过自己寻找解决方案-$ watch或reload:似乎建议将其作为修复程序,但我无法以我的情况使用它们.

I'm totally new to Angular and have tried to find solutions to this myself - $watch or reload: true seem to be suggested as fixes, but I cannot get them to work in my case.

路线

  .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)
         });

})

在我的控制台上,我第一次阅读新闻时,先运行工厂,然后运行控制器,但是如果我要提取更多数据,然后破解新闻,则只有控制器运行,除非我刷新,然后两者都运行再次.

Looking at my console, the first time I read the news, the factory then controller run, but if I go to pull more data down, then go hack to news, only the controller runs, unless I refresh, then both run again.

我不需要新闻视图在仍处于实时"状态下进行更新(但是如果可以做到这一点,那就更好了)-只是当您在应用程序中的其他位置返回新闻时,才可以获取新数据

I do not need the news view to update 'live' while still on it (but if that can be easilly done all the better) - just to pick up new data when you go back to news after being elsewhere in the app.

谢谢.

推荐答案

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

Factories return singletons and only run once. The object newsService is cached by angular. The var declarations for newsHeadlines and newsHeadlinesObj will only ever run once; meaning your promise returning methods will always resolve the promise with the same data that was retrieved when your factory was first instantiated. You should put them in a function and call it from your find methods on the singleton object.

.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-我确定您知道并且打算以后做一些不同的事情,或者以防万一,以防万一:不要在这里使用promises是毫无意义的,并且您不需要在这里使用$q.您可以简单地返回数据而不是返回承诺.

PS - I'm sure you know and are planning to do things differently later or something, but just in case you don't: Using promises here is pointless and you have no need for $q here. You could simply return the data instead of returning the promises.

这篇关于角度控制器需要刷新以在工厂承诺中获取新数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆