Pregunta

Estoy trabajando en una aplicación de administración con angularjs. La aplicación obtiene sus datos del servidor usando $ recurso. Termino con objetos de datos que contienen una propiedad '$ promesa' para determinar cuándo se han recuperado los datos. Todo está bien.

Ahora, esta aplicación de administración también puede crear nuevos objetos. Esos nuevos objetos son administrados por los mismos controladores que el que generalmente proviene de '$ recurso'.

Así que ahora tengo 2 tipos de objetos:

  • objetos con $ promesa de propiedad. Debería usar $ Promise.Then () antes de manipularlos con datos completos
  • objetos lisos. No tienen una propiedad de $ promesa, su valor es accesible instantáneamente

Me gustaría reducir el código y tener un solo uso de un solo uso, no tener que verificar si se resuelve los datos de objetos, o si no es una promesa.

¿Hay algún problema para construir mis objetos 'simples' agregándolos una propiedad de '$ promesa' que ya se resuelve a sí mismos? De esa manera, siempre usaría 'MyObject. $ Promise.Then ()'.

¿Hay algún patrón común para manejar esta situación? No pude encontrar ningún método 'estándar' para crear este tipo de objetos con angular.

¿Fue útil?

Solución

Usted podría usar $ q. cuando si no está seguro de si El objeto tiene una promesa o no.

(obj.$promise ? obj.$promise || $q.when(objResult)).then(function(result){
          //handle success case.
          //Incase of object not having the $promise property result will be object itself
}) 

Si la propiedad resultante no tiene una promesa, esto se resolverá con la promesa.

Envuelve un objeto que podría ser un valor o un (tercero) que se puede prometer en una promesa de $ q. Esto es útil cuando se trata de un objeto que podría o no ser una promesa, o si la promesa proviene de una fuente que no se puede confiar.

No necesita crear siempre una promesa y adjuntarlo en los datos que se están transfiriendo, en lugar de eso, podría hacer que sus métodos devuelvan la promesa. Ejemplo: -

   function getCurrentUserData(userId){
       var defered = $q.defer();
       ... 
       //Check in my cache if this is already there, then get it from cache and resolve it
       defered.resolve(objectFromCache);
      //my else condition
      //It is not in cache so let me make the call.
      $http.get('myurl').then(function(result){
            //Do validation with data and if it doesnot match then reject it
            defered.reject(reason);
             //Else Do something with the data put it into the cache, mapping logic etc..
             defered.resolve(dto);


      }).catch(function(error){
            //do something with error and then reject
            defered.reject(reasonDerived);
      });
      return defered.promise;
   }

Aquí hay una versión simplificada y menos explícita (Crédito: Benjamin Gruenbaum):

var cached = null;
function getCurrentUserData(userId){
    return cached = cached || $http.get('myurl').then(function(result){
        if(isNotValid(result)) return $q.reject(reason); // alternatively `throw`
        return transformToDto(result);
    }, function(response){
     if(checkforsomethingonstatusandreject)
       return $q.reject('Errored Out')
     //do some actions to notify the error scenarios and return default actions
     return someDefaults; });
    }

Puede, por supuesto, generalmente, en lugar de devolver la razón y transformarla en función de otras verificaciones, la idea está almacenando en caché la promesa en lugar del valor. Esto también tiene la ventaja de no hacer múltiples solicitudes HTTP si el método se llama antes de que regrese una vez.

ahora que siempre podría hacer: -

    getCurrentUserData(userid).then(function(user){

    }).catch(function(error){

    });

Las promesas pueden ser encadenadas también. Así que también podrías hacer esto: -

   return $resource('myresource').$promise.then(function(result){
          //Do some mapping and return mapped data
         return mappedResult;
    });

Otros consejos

Las promesas A + deben ofrecer un método estático:

Promise.resolve(val);

... lo que genera una promesa previamente resuelta.Debe devolver uno de estos si su biblioteca de promesas ofrece esto.Estupendo.Hago esto con frecuencia para evitar la duplicación de la interfaz.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top