2014-09-25 3 views
1

Я думаю, что неправильно написано свое обещание, и я не мог понять, почему он кэширует данные. Случается, что, допустим, я вошел в систему как scott. Когда приложение запускается, оно будет подключаться к конечной точке, чтобы захватить список имен устройств и сопоставление устройств. В данный момент он отлично работает.AngularJS обещание - кеширование

Когда я выхожу из системы, и я не обновляю браузер, и я вхожу в систему как другой пользователь, имена устройств, которые scott извлекаются на той же вкладке браузера, это видно недавно зарегистрированному пользователю. Тем не менее, я вижу на моей вкладке сети Chrome, что конечная точка вызвана, и она получила правильный список имен устройств.

Так что я думал о добавлении функции destroyDeviceListing на моем фабрике, надеясь, что смогу очистить значения. Эта функция вызывается во время выхода из системы. Однако это не помогло. Ниже моя фабрика

app.factory('DeviceFactory', ['$q','User', 'DeviceAPI', function($q, User, DeviceAPI) { 

    var deferredLoad = $q.defer(); 
    var isLoaded = deferredLoad.promise; 
    var _deviceCollection = { deviceIds : undefined }; 

    isLoaded.then(function(data) { 
     _deviceCollection.deviceIds = data; 
     return _deviceCollection; 
    }); 

    return { 

     destroyDeviceListing : function() { 
      _deviceCollection.deviceIds = undefined; 
      deferredLoad.resolve(_deviceCollection.deviceIds); 
     }, 

     getDeviceIdListing : function() { 

      return isLoaded; 
     }, 

     getDeviceIdMapping : function(deviceIdsEndpoint) { 
      var deferred = $q.defer(); 
      var userData = User.getUserData(); 

      // REST endpoint call using Restangular library 
      RestAPI.setBaseUrl(deviceIdsEndpoint); 
      RestAPI.setDefaultRequestParams({ userresourceid : userData.resourceId, tokenresourceid : userData.tokenResourceId, token: userData.bearerToken }); 
      RestAPI.one('devices').customGET('', { 'token' : userData.bearerToken }) 
       .then(function(res) { 
        _deviceCollection.deviceIds = _.chain(res) 
         .filter(function(data) { 
          return data.devPrefix != 'iphone' 
         }) 
         .map(function(item) { 
          return { 
           devPrefix : item.devPrefix, 
           name : item.attributes[item.devPrefix + '.dyn.prop.name'].toUpperCase(), 
          } 
         }) 
         .value(); 
        deferredLoad.resolve(_deviceCollection.deviceIds); 

        var deviceIdMapping = _.chain(_deviceCollection.deviceIds) 
         .groupBy('deviceId') 
         .value(); 

        deferred.resolve(deviceIdMapping); 
       }); 
      return deferred.promise; 
     } 
    } 
}]) 

и ниже отрывок из моего контроллера, укороченной и очищено версия

.controller('DeviceController', ['DeviceFactory'], function(DeviceFactory) { 

    var deviceIdMappingLoader = DeviceFactory.getDeviceIdMapping('http://10.5.1.7/v1'); 
    deviceIdMappingLoader.then(function(res) { 

     $scope.deviceIdMapping = res; 

     var deviceIdListingLoader = DeviceFactory.getDeviceIdListing(); 
     deviceIdListingLoader.then(function(data) { 
      $scope.deviceIDCollection = data; 
     }) 
    }) 
}) 
+0

Ожидаете ли вы, что делать какие-либо кэширование? – Bergi

+0

Нет, мне не нравятся данные кэша. Мне нужно использовать обещание, чтобы я был уверен, что данные прибыли, и я могу назвать следующие функции или коды. – devwannabe

+0

Обещание после разрешения не может снова решить другое значение. В функции destroy снова создайте обещание 'deferredLoad = $ q.defer()' – Chandermani

ответ

1

Ну, вы получили только один var deferredLoad в целом приложение. Поскольку обещание представляет собой только один асинхронный результат, отложенные могут быть разрешены только один раз. Вам нужно будет создать новый отложенный для каждого запроса - хотя вам вообще не нужно будет create a deferred, вы можете просто использовать обещание, которое у вас уже есть.

Если вы не хотите кеширования, вы не должны иметь глобальные переменные deferredLoad, isLoaded и _deviceCollection в вашем модуле. Просто сделайте

app.factory('DeviceFactory', ['$q','User', 'DeviceAPI', function($q, User, DeviceAPI) { 
    function getDevices(deviceIdsEndpoint) { 
     var userData = User.getUserData(); 
     // REST endpoint call using Restangular library 
     RestAPI.setBaseUrl(deviceIdsEndpoint); 
     RestAPI.setDefaultRequestParams({ userresourceid : userData.resourceId, tokenresourceid : userData.tokenResourceId, token: userData.bearerToken }); 
     return RestAPI.one('devices').customGET('', { 'token' : userData.bearerToken }) 
     .then(function(res) { 
      return _.chain(res) 
      .filter(function(data) { 
       return data.devPrefix != 'iphone' 
      }) 
      .map(function(item) { 
       return { 
        devPrefix : item.devPrefix, 
        name : item.attributes[item.devPrefix + '.dyn.prop.name'].toUpperCase(), 
       }; 
      }) 
      .value(); 
     }); 
    } 
    return { 
     destroyDeviceListing : function() { 
      // no caching - nothing there to be destroyed 
     }, 
     getDeviceIdListing : function(deviceIdsEndpoint) { 
      return getDevices(deviceIdsEndpoint) 
      .then(function(data) { 
       return { deviceIds: data }; 
      }); 
     }, 
     getDeviceIdMapping : function(deviceIdsEndpoint) { 
      return this.getDeviceIdListing(deviceIdsEndpoint) 
      .then(function(deviceIds) { 
       return _.chain(deviceIds) 
       .groupBy('deviceId') 
       .value(); 
      }); 
     } 
    }; 
}]) 

Теперь, чтобы добавить кэширование вы бы просто создать глобальную переменную обещание и сохранить обещание там после того, как запрос будет создан:

var deviceCollectionPromise = null; 
… 
return { 
    destroyDeviceListing : function() { 
     // if nothing is cached: 
     if (!deviceCollectionPromise) return; 
     // the collection that is stored (or still fetched!) 
     deviceCollectionPromise.then(function(collection) { 
      // …is invalidated. Notice that mutating the result of a promise 
      // is a bad idea in general, but might be necessary here: 
      collection.deviceIds = undefined; 
     }); 
     // empty the cache: 
     deviceCollectionPromise = null; 
    }, 
    getDeviceIdListing : function(deviceIdsEndpoint) { 
     if (!deviceCollectionPromise) 
      deviceCollectionPromise = getDevices(deviceIdsEndpoint) 
      .then(function(data) { 
       return { deviceIds: data }; 
      }); 
     return deviceCollectionPromise; 
    }, 
    … 
}; 
+0

Yup, как упоминалось ранее Чандермани, у меня была только одна отложенная переменная. Я не знал об этом. Попытка это сейчас :) – devwannabe

+0

Только что заметили, что вы обновили свой ответ. Что делать, если мы хотим обновить кеш, как мы будем писать новую функцию, называемую createNewDeviceListing()? – devwannabe

+0

Я думаю, что это было бы очень похоже на функцию 'destroyDiviceListing', которую я опубликовал, в зависимости от того, что именно вы хотите. – Bergi