2016-04-11 19 views
0

Ich habe diesen Code, dessen Ergebnis entweder als gelöstes oder abgelehntes Versprechen zurückgegeben werden soll.Wie löst man ein JQuery-Versprechen basierend auf der Benutzereingabe

var runChecks = function(hasClickId, maxClicksModeIsNotOff) { 
    var dfd = $.Deferred(); 

    clickIdCheckPassed = hasClickId; // equals false 
    maxClicksCheckPassed = maxClicksModeIsNotOff; // equals false 

    if (!clickIdCheckPassed) { 
     clickIdCheckPassed = runClickIdCheck(); 
    } 

    if (!maxClicksCheckPassed) { 
     maxClicksCheckPassed = runMaxClicksCheck(); 
    } 

    if (maxClicksCheckPassed && clickIdCheckPassed) { 
     dfd.resolve('Resolved'); 
    } else { 
     dfd.reject('rejected'); 
    } 

    return dfd.promise(); 
}; 

Funktionen runClickIdCheck() und runMaxClicksCheck() collect Benutzereingaben und basierend auf ihr lag, bringe entweder true oder false. Wenn beiden resultierenden Werte true sind, soll ich das Versprechen lösen, sonst sollte es verworfen werden - daher die bedingten:

if (maxClicksCheckPassed && clickIdCheckPassed) { 
    dfd.resolve('Resolved'); 
} else { 
    dfd.reject('Rejected'); 
} 

Allerdings ist das Problem, dass der Code nicht für die Benutzereingaben warten und jedes Mal, wertet die Versprechen als "abgelehnt", noch bevor der Benutzer irgendeine Eingabe gegeben hat.

Als Referenz ist dies, wie runClickIdCheck Funktion wie folgt aussieht:

var runClickIdCheck = function() { 
    bootbox.confirm('Are you sure?', function(result) { 
     if (result) { 
      return true; 
     } 
    }); 
    return false; 
}; 

Wie ich diesen Code machen kann wie erwartet verhalten, so dass ich das Versprechen zu ‚lösen‘ zu bewerten nur, wenn die Funktionen abhängig von Benutzereingaben beide sind wahr?

Edit:

Das erwartete UI Verhalten ist, dass das Formular nur abgegeben werden, wenn der Benutzer zweimal den Dialog bestätigt:

$form.submit(function(e) { 
    e.preventDefault(); 
    $.when(runChecks(hasClickId, maxClicksModeIsNotOff)).then(
     function(status) { 
      $form.submit() 
     }, 
     function(status) { 
      return false; 
     } 
    ); 
} 

Aus diesem Grund dachte ich, das Versprechen inteface das tun würde, Job. Das Versprechen sollte gelöst werden, wenn runClickIdCheck() und runMaxClicksCheck() zu true ausgewertet werden.

+0

Ich denke, Sie missbrauchen Versprechungen hier. Ihr Scheck scheint völlig synchron zu sein, also (obwohl es möglich ist) ist es nicht wirklich notwendig, ihn in eine Versprechenssemantik zu verwandeln. Führen Sie den Check einfach aus, wenn Sie ihn ausführen müssen. Erläutern Sie mehr über das Problem, das Sie zu lösen versuchen, d. H. Welches UI-Verhalten möchten Sie implementieren? Fügen Sie außerdem das erforderliche Markup hinzu, das es veranschaulicht. – Tomalak

+0

@Tomalak Sieht aus wie 'runClickIdCheck' Methode async ist. OP sollte Logik in relevanten Callback setzen oder diese Plugin-Methode (die ich nicht kenne) behandelt Promise-Schnittstelle –

+0

@ A.Wolff Ah, das ist natürlich richtig. – Tomalak

Antwort

1

Während ist es möglich,, um diese Arbeit mit $.Deferred() machen, bezweifle ich, dass es sich lohnt.

Ich habe vor dem Schreiben des folgenden Codes eine auf Versprechen basierende Lösung implementiert und es stellte sich heraus, dass sie viel länger und viel weniger klar ist, als nur den Callback-basierten Ansatz zu verwenden, den bootbox bietet.

Halten Sie es einfach.

$("#form").submit(function (e) { 
    var self = this; 

    e.preventDefault(); 

    bootbox.confirm('Question 1', function (confirmed1) { 
     if (!confirmed1) return; 

     bootbox.confirm('Question 2', function (confirmed2) { 
      if (!confirmed2) return; 

      $.post(self.action, $(self).serialize()).done(function (data) { 
       // Ajax post has finished successfully 
      }); 
     }); 
    }); 
}); 
Verwandte Themen