2017-03-10 6 views
1

Bitte entschuldigen Sie, wenn dies in irgendeiner Weise offensichtlich ist, aber ich kann nichts ähnliches in den Angularjs Docs oder auf SO finden. Ich habe einen Antrag, wo es eine Tabelle mit Daten gibt, einschließlich Schätzungen nach Monat. Wir implementieren etwas, wo Sie die Schätzung von einem Monat auf einen anderen ziehen und ablegen können, um einige schnelle Änderungen vorzunehmen. Ich laufe in eine ungerade Ausgabe:Problem mit verschachtelten Ressourcenaufrufen in angularjs

Ressource:

function updatableResource(url){ 
    return $resource(url+":id/", {id: '@id'}, 
    { 
     'update': { 
     method:'PUT', 
     }, 
    } 
); 
} 

// in API definition file 
Estimate: foo.updatableResource('<URL>'), 

Das funktioniert gut, und ich kann in der Regel $update oder $save ohne Problem nennen

In diesem Fall aber ich brauche zu bearbeiten zwei Dinge gleichzeitig, und möglicherweise sogar einen löschen. Also muss ich wissen, ob die erste erfolgreich war, bevor ich die zweite mache. Wenn ich zum Beispiel eine Schätzung von einem Monat auf eine andere ohne Schätzung verschiebe, mache ich zuerst die neue Schätzung und lösche dann die alte. Ich würde denken, ich etwas tun könnte:

// source and target are objects that each contain an estimate from a different month. 

successFunc = function() { 
    source.estimate.$delete(
     function() { 
      <refresh stuff> 
     }, 
     function(rejection) { 
      alert("Unable to delete source estimate."); 
     } 
    ); 
}; 

errorFunc = function(rejection) { 
    <undo stuff> 
    alert("Unable to add money to target estimate."); 
}; 

// POST if new, PUT if updating 
if (isNewEstimate) { 
    target.estimate.$save(successFunc, errorFunc); 
} else { 
    target.estimate.$update(successFunc, errorFunc); 
} 

So in diesem Code die Schätzung Erstellung/Aktualisierung funktioniert gut, aber ich kann nicht $ Ressource rufen fordert die Quelle Schätzung in der Erfolgsfunktion. Ich bekomme den Fehler TypeError: source.estimate.$delete is not a function Wenn ich es außerhalb dieser Funktion (auf der gleichen Ebene wie das Ziel speichern/aktualisieren Aufruf) es funktioniert aber.

In meiner Forschung habe ich etwas gefunden, die Art gearbeitet:

Api.Estimate.delete(source.estimate, 
<success and failure functions> 
... 

, dass die Streichung der Arbeit gemacht, aber nichts anderes scheint das Löschen zu erkennen und ich brauche eine teure manuelle Wieder Abfrage tun, um für es funktioniert. Gibt es etwas seltsames am Umfang, da es sich um eine Callback-Funktion handelt? Ich kann einfach nicht herausfinden, warum es nicht in dieser Funktion arbeiten ...

EDIT:

Bei der weiteren Prüfung, es scheint sich ein Problem mit den Objekten zu sein:

source.estimate 
Object 
    amount: 12345 
    date: "2017-02-25" 
    foo: "ABC" 
    id: 4715 
    bar: 987 
    baz: 123 
    __proto__: Object 

target.estimate 
d 
    $promise: undefined 
    $resolved: true 
    amount: 12345 
    date: "2017-03-25" 
    foo: "ABC" 
    id: 4716 
    bar: 987 
    baz: 123 
    __proto__: Object 

So scheint das Ziel, das vom Typ d ist, zu arbeiten, während die Quelle, die nur ein Standardobjekt ist, nicht funktioniert. Wenn ich die Ziehrichtung umkehre, bekomme ich dieselbe Art von Ergebnis. Quelle ist immer ein Objekt, und Ziel ist immer d (was ich vermute, ist wegen der verkleinerten JS).

+1

Ich habe auf dieses Problem bei der Verwendung von $ Ressource ... gerannt, weshalb ich auf gerade $ http wechselte, aber wenn Sie Console.log (source.estimate) hat es tatsächlich einen Wert an diesem Punkt? – Dylan

+0

Wie ich oben in meiner Bearbeitung hinzugefügt habe, schien das Objekt normal zu sein (da darin die Felder und Werte erwartet wurden), aber es stellt sich heraus, dass die tatsächlichen Objekte unterschiedlich sind. – zaknotzach

Antwort

0

Das Problem mit dem Plugin bezogen werden tatsächlich stellte sich heraus, dass ich die Objekte zu erhalten, wurde mit.Aus irgendeinem Grund vermasselte es einen von ihnen, und obwohl es die gleichen Eigenschaften hatte, war es kein richtiger $resource mehr, weshalb ich die Funktion nicht aufrufen konnte. Es schien nur so, als ob es mit dem aufrufenden Layout zusammenhing, wegen der Reihenfolge, in der ich einige Funktionen anrief.

0

Die Instanzmethoden von $ Ressourcenobjekten sind Versprechen und können mit Standard-Verkettungsverfahren verkettet werden:

$scope.resource1 = updatableResource().get({id: 1}); 
$scope.resource2 = updatableResource().get({id: 2}); 

$q.all([$scope.resource1.$promise, $scope.resource2.$promise]) 
    .then(function(resArray) { 
    var res1 = resArray[0]; 
    var res2 = resArray[1]; 
    //Process results 
    //Return promise to chain 
    return $q.all([res1.$update(), res2.$update()]); 
}).then(function(resArray) { 
    var res1 = resArray[0]; 
    var res2 = resArray[1]; 
    //Do next thing 
}); 

Da die Methode .then Aufruf eines Versprechens, ein neues abgeleiteten Versprechen zurück, es leicht möglich ist, eine Kette von Versprechen schaffen.

Es ist möglich, Ketten beliebiger Länge zu erstellen, und da ein Versprechen mit einem anderen Versprechen gelöst werden kann (was seine Auflösung weiter verzögert), ist es möglich, die Auflösung der Versprechen an jedem Punkt der Kette anzuhalten/zu verschieben. Dies ermöglicht die Implementierung leistungsfähiger APIs.

— AngularJS $q Service API Reference - Chaining Promises

Verwandte Themen