2010-10-15 6 views
2

J'ai un objet javascript avec plusieurs propriétés. L'objet contient également une méthode d'instance qui renvoie le résultat d'un calcul sur deux des propriétés de l'objet. J'utilise le nouveau plugin JQuery .link() (http://api.jquery.com/link/), pour mettre à jour l'interface utilisateur et les éléments de formulaire avec les valeurs de propriété d'objet et vice versa, chaque fois que le formulaire ou l'objet est mis à jour.jQuery Datalink ne fonctionne pas avec les méthodes objet

Tout cela fonctionne à l'exception de l'un des éléments de formulaire, qui doit contenir le résultat de la méthode d'instance de l'objet mais ne sera jamais mis à jour.

J'ai mis un bouton sur le formulaire pour vérifier manuellement la valeur de Discrepancy, et cela fonctionne mais le plugin jquery link ne remplit pas les éléments d'entrée automatiquement, bien qu'il remplisse les éléments d'entrée liés aux propriétés de l'objet. Tous les éléments ont un identifiant et un nom. Est-ce que quelqu'un peut me dire où je me trompe?

Mon javascript:

<script> 

    function Product() { 
     this.InStock = 0; 
     this.Ordered = 0; 

    } 

    // object's instance method 
    Product.prototype.Discrepancy = ComputeDiscrepancy; 

    function ComputeDiscrepancy() { 
     return this.InStock - this.Ordered; 
    } 

    $(document).ready(function() { 

     var products = new Array(); 

     products[0] = new Product(); 
     products[1] = new Product(); 

     $("form").link(products[0], { 
      InStock: "product0_InStock", 
      Ordered: "product0_Ordered", 
      Discrepancy: "product0_Discrepancy" 
     }); 

     $("form").link(products[1], { 
      InStock: "product1_InStock", 
      Ordered: "product1_Ordered", 
      Discrepancy: "product1_Discrepancy" 
     }); 
     // button for me to manually check discrepancy method works 
     $("#checkData").click(function() { 
      alert(products[0].InStock); 
      $("#product0_Discrepancy").val(products[0].Discrepancy()); 
     }); 

    }); </script> 

HTML:

<table> 
    <tr> 
     <th></th><th>Product 1</th><th>Product 2</th> 
    </tr> 
    <tr> 
     <td> In Stock</td> 
     <td><input id="product0_InStock" name="product0_InStock"/></td> 
     <td><input id="product1_InStock" name="product1_InStock"/></td> 

    </tr> 

    <tr> 
     <td>Ordered</td> 
     <td><input id="product0_Ordered" name="product0_Ordered"/></td> 
     <td><input id="product1_Ordered" name="product1_Ordered"/></td> 
    </tr> 

    <tr> 
     <td>Discrepancy</td> 
     <td><input id="product0_Discrepancy" name="product0_Discrepancy"/></td> 
     <td><input id="product1_Discrepancy" name="product1_Discrepancy"/></td> 
    </tr> 

</table> 
+0

Je ne vois pas un élément de forme partout - est-il absent de la page, ou tout simplement omis de votre exemple? –

+0

C'est dans la page, j'ai juste omis de mon exemple. – Robini

Répondre

1

Le problème est que Divergence est une méthode d'un objet produit et non une propriété. Vous ne pouvez pas lier un élément DOM à une méthode, uniquement à une propriété. La façon dont j'ai résolu le problème consiste à (a) faire de Discrepancy une propriété, et (b) utiliser les méthodes convert et convertBack afin de s'assurer que cette nouvelle propriété a été correctement mise à jour.

Voici mon bloc de script:

function Product() { 
    this.InStock = 0; 
    this.Ordered = 0; 
    this.Discrepancy = 0; 
} 

var products = []; 

$(document).ready(function() { 

    products[0] = new Product(); 
    products[1] = new Product(); 

    var calcDiscrepancy = function(value, source, target) { 
     $(target).data("Discrepancy", target.InStock - target.Ordered); 
     return value; 
    }; 

    var changeInStock = function (value, source, target) { 
     target.InStock = value; 
     return calcDiscrepancy(value, source, target)   ; 
    }; 

    var changeOrdered = function (value, source, target) { 
     target.Ordered = value; 
     return calcDiscrepancy(value, source, target)   ; 
    }; 

    var showDiscrepancy = function(value, source, target) { 
     $(target).text(value.toString()); 
    }; 

    $("form").link(products[0], { 
     InStock: { 
      name: "product0_InStock", 
      convert: changeInStock 
     }, 
     Ordered: { 
      name: "product0_Ordered", 
      convert: changeOrdered 
     }, 
     Discrepancy: { 
      name: "product0_Discrepancy", 
      convertBack: showDiscrepancy 
     } 
    }); 

    $("form").link(products[1], { 
     InStock: { 
      name: "product1_InStock", 
      convert: changeInStock 
     }, 
     Ordered: { 
      name: "product1_Ordered", 
      convert: changeOrdered 
     }, 
     Discrepancy: { 
      name: "product1_Discrepancy", 
      convertBack: showDiscrepancy 
     } 
    }); 
}); 

Aller au travers:

  1. ajouter la propriété Discrepancy à la classe Product, par défaut 0. Throw de suite les choses de ComputeDiscrepancy.

  2. écrire quelques fonctions qui prennent note des changements dans InStock et Ordered. Ceux-ci mettront à jour les propriétés pertinentes de l'objet cible, puis appellent une fonction appelée calcDiscrepancy et renvoient sa valeur de retour.

  3. calcDiscrepancy va mettre à jour la valeur de la propriété Discrepancy de l'objet cible. Pour m'assurer que tous les événements sont déclenchés avec cette modification, j'ai utilisé la méthode .data() de jQuery.

  4. écriture d'une méthode showDiscrepancy qui mettrait à jour le contenu de la cible avec la valeur transmise (la cible sera l'élément DOM). J'ai également changé les éléments de "divergence" en plutôt que les zones de texte: cela n'avait pas de sens autrement.

  5. Les appels à link() mappent maintenant les éléments DOM pertinents aux propriétés pertinentes et spécifient des convertisseurs pour chacun. Pour la propriété InStock, le convertisseur est un type de conversion et appelle changeInStock, etc.Pour la propriété Discrepancy, le convertisseur est un type convertBack qui appelle showDiscrepancy. (En substance convert va de l'élément DOM à la propriété d'objet, et convertBack va de la propriété à l'élément.)

+0

Merci boyetboy, j'ai eu très peu d'aide avec ce problème, alors je vous remercie de votre réponse. Je vais supporter ce que vous avez dit à l'esprit à l'avenir. Depuis, je me suis éloigné du plugin link de jQuery et j'ai jeté un œil sur backbone.js avant de me lancer sur knockout.js, pour avoir ajouté ce type de fonctionnalité à mes applications. – Robini