2017-03-28 3 views
0

niveau débutant javascript question ...

je dois définir un modèle cellulaire pour mon KOGrid qui dépend des valeurs dans ma VM. Je veux que le texte s'affiche en vert si un champ associé est True sinon afficher en rouge.

je les modèles cellulaires suivants:

var accountEditTemplate = `<div><input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[$data.field]" /> 
           <span data-bind=\"visible: !$parent.selected(), 
            text: $parent.entity[$data.field], 
            css: $parent.entity.accountIsValid() === 'True' ? \'passed-validation\' : \'failed-validation\'"> 
           </span> 
          </div>`; 

    var costCentreEditTemplate = `<div><input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[$data.field]" /> 
           <span data-bind=\"visible: !$parent.selected(), 
            text: $parent.entity[$data.field], 
            css: $parent.entity.costCentreIsValid() === 'True' ? \'passed-validation\' : \'failed-validation\'"> 
           </span> 
          </div>`; 

Ces obtenir utilisés dans mes columnDefs comme suit

self.columnDefs = [ 
     { width: 100, field: 'supplierNo', displayName: 'Supplier No', cellTemplate: supplierEditTemplate }, 
     { width: 150, field: 'invoiceNo', displayName: 'Invoice No' }, 
     { width: 150, field: 'costCentre', displayName: 'Cost Centre (Dim1)', cellTemplate: costCentreEditTemplate }, 
     { width: 200, field: 'glAccount', displayName: 'GL Account (Account)', cellTemplate: accountEditTemplate }, 
     { width: 100, field: 'amount', displayName: 'Amount' }, 
     { width: 300, field: 'invoiceDesc', displayName: 'Invoice Description' }, 
     { width: 150, field: 'accountIsValid', displayName: 'Valid Account' }, 
     { width: 150, field: 'costCentreIsValid', displayName: 'Valid Cost Centre' }, 
     { width: 150, field: 'supplierIsValid', displayName: 'Valid Supplier' }, 
    ]; 

Cela fonctionne bien, mais je veux réduire la duplication de code en ayant une fonction d'aide qui retournera le modèle de cellule. Quelque chose comme:

function GetCellTemplate(fieldName, isValid) 
{ 
    var template = `<div><input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[fieldName]" /> 
            <span data-bind=\"visible: !$parent.selected(), 
             text: $parent.entity[fieldName], 
             css: isValid === 'True' ? \'passed-validation\' : \'failed-validation\'"> 
            </span> 
           </div>`; 

    switch(expression) { 
     case 'account': 
      return template 
      break; 
     default: 

    } 
} 

Cela pourrait être appelé par:

var accountEditTemplate = GetCellTemplate('account', $parent.entity.accountIsValid()); 

Mon problème est quand j'essaie cela, je me ReferenceError: $ parent n'est pas définie

Quelle est la meilleure façon de résoudre ce copier & croissance de code pâte - je vais le même genre de fonctionnalité pour de nombreux domaines?

code mis à jour selon la suggestion de Jason - ne fonctionne pas encore

function GetCellTemplate(fieldName, validationFieldName) { 
    var template = `<div><input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[{fieldName}]\" /> 
        <span data-bind=\"visible: !$parent.selected(), 
         text: $parent.entity[{fieldName}], 
         css: $parent.entity.{validationFieldName} === 'True' ? \'passed-validation\' : \'failed-validation\'\"> 
        </span> 
       </div>`; 
    } 

var editBatchVm = function() { 
    var self = this; 
    var $loadingIndicator = $('#loading-indicator'); 

    // Properties 
    self.recs = ko.observableArray([]); 
    self.selected = ko.observableArray(); 

    var accountEditTemplate = GetCellTemplate('account', 'accountIsValid'); 
    var costCentreEditTemplate = GetCellTemplate('costCentre', 'costCentreIsValid'); 
    var supplierEditTemplate = GetCellTemplate('supplier', 'supplierIsValid'); 

    self.columnDefs = [ 
     { width: 100, field: 'supplierNo', displayName: 'Supplier No', cellTemplate: supplierEditTemplate }, 
     { width: 150, field: 'invoiceNo', displayName: 'Invoice No' }, 
     { width: 150, field: 'costCentre', displayName: 'Cost Centre (Dim1)', cellTemplate: costCentreEditTemplate }, 
     { width: 200, field: 'glAccount', displayName: 'GL Account (Account)', cellTemplate: accountEditTemplate }, 
     { width: 100, field: 'amount', displayName: 'Amount' }, 
     { width: 300, field: 'invoiceDesc', displayName: 'Invoice Description' }, 
     { width: 150, field: 'accountIsValid', displayName: 'Valid Account' }, 
     { width: 150, field: 'costCentreIsValid', displayName: 'Valid Cost Centre' }, 
     { width: 150, field: 'supplierIsValid', displayName: 'Valid Supplier' }, 
    ]; 
+0

Vous aurez accès à '$ l'objet parent' dans le contexte de liaison knock-out pas à l'intérieur de votre modèle JS. Vous devez transmettre le modèle parent par référence. –

Répondre

1

À moins que je me trompe, vous êtes juste la construction d'une chaîne qui sera plus tard exécutés comme un modèle donc il n'y a pas besoin de passer dans le réel objet de validation lors de la construction du modèle, vous avez juste besoin de la chaîne qui représente l'objet de validation. Le modèle lui-même peut référencer le contexte $ parent plus tard quand il est exécuté.

var accountEditTemplate = GetCellTemplate('account', 'accountIsValid'); 

...

function GetCellTemplate(fieldName, validationFieldName) { 
    var template = "<div><input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[" + fieldName + "]\" />" + 
        " <span data-bind=\"visible: !$parent.selected()," + 
        "  text: $parent.entity[" + fieldName + "]," + 
        "  css: $parent.entity." + validationFieldName + " === 'True' ? \'passed-validation\' : \'failed-validation\'\">" + 
        " </span>" + 
        "</div>"; 
    ... 
} 
+0

Merci pour la réponse, mais cela ne fonctionne pas pour moi. Aucune erreur, mais il semble que les valeurs des paramètres reçus par GetCellTemplate ne soient pas insérées dans la chaîne. J'ai mis à jour la question avec le code utilisé –

+0

@RobBowman Si vous n'utilisez pas un compilateur javascript ES6, vous devrez probablement le convertir en une concaténation de chaîne traditionnelle comme "text: $ parent.entity [" + fieldName + "] ", –

+0

@RobBowman Mise à jour de l'exemple pour utiliser la concaténation de chaîne. –