web-dev-qa-db-fra.com

knockout.js - valeur par défaut du texte de liaison de données

Dans knockout.js, j'ai un champ très standard qui ressemble à ceci:

<label data-bind="text: JobTitle"></label>

Ce que j'aimerais, c'est d'avoir une valeur par défaut spécifiée ici si la valeur du texte est nulle, par exemple "Aucun titre de travail spécifié".

Est-ce possible de faire dans knockout.js?

Merci.

24
Adam Levitt

Je suppose donc que vous voulez une vraie valeur par défaut et pas seulement un texte d'espace réservé. Voici un moyen de le faire avec un répéteur;

ko.extenders.defaultIfNull = function(target, defaultValue) {
    var result = ko.computed({
        read: target,
        write: function(newValue) {
            if (!newValue) {
                target(defaultValue);
            } else {
                target(newValue);
            }
        }
    });

    result(target());

    return result;
};

var viewModel = function() {
   this.someValue = ko.observable().extend({ defaultIfNull: "some default" });
};

ko.applyBindings(new viewModel());

http://jsfiddle.net/madcapnmckay/aTMpp/

J'espère que cela t'aides.

18
madcapnmckay

Le moyen le plus court/le plus simple est probablement:

<label data-bind="text: JobTitle()||'No Job Title Specified'"></label>

Exemple de travail:

var ViewModel = function() {
    this.jobTitle = ko.observable();
};
 
ko.applyBindings(new ViewModel());
body { font-family: arial; font-size: 14px; }
.liveExample { padding: 1em; background-color: #EEEEDD; border: 1px solid #CCC; max-width: 655px; }
.liveExample input { font-family: Arial; }
.liveExample b { font-weight: bold; }
.liveExample p { margin-top: 0.9em; margin-bottom: 0.9em; }
.liveExample select[multiple] { width: 100%; height: 8em; }
.liveExample h2 { margin-top: 0.4em; font-weight: bold; font-size: 1.2em; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class='liveExample'>   
    <p>Job Title: <input data-bind='value: jobTitle' /></p> 
    <h2 data-bind="text: jobTitle()||'No Job Title Specified'"></h2>  
</div>

Ou JS Fiddle: http://jsfiddle.net/735qC/43/

49
rjmunro

Encore plus court que les autres exemples de code est le suivant:

ko.extenders.withDefault = function(target, defaultValue) {
    target.subscribe(function(input) {
        if(!input) target(defaultValue)
    });
    return target
};

Avec l'initiation

ko.observable().extend({ withDefault: "some Default" })
3
K. Rohde

Vous pouvez le faire comme ceci:

<label data-bind="text: JobTitle() != undefined && JobTitle() != null ? JobTitle() : 'No Job Title Specified'"></label>

Avec le contrôle non défini, vous pouvez vérifier si vous avez cette fonction ou non lorsque vous chargez la page pour la première fois.

1
Bura Chuhadar

Il peut être utile d'avoir une valeur par défaut à des fins d'affichage uniquement, au lieu d'appliquer des extensions qui toujours renvoient une valeur par défaut.

Avec cela, les propriétés de votre modèle restent vides, ce qui est mieux par exemple lorsqu'il s'agit de validation (vérification des propriétés vides) ou de renvoi de données au serveur (vous ne voudrez peut-être pas renvoyer cette valeur par défaut).

Vous pouvez utiliser la liaison personnalisée dans l'exemple suivant, qui est basé sur la liaison de texte, qui rend le texte par défaut fourni ou - si non fourni (vous pouvez bien entendu l'adapter à vos besoins):

ko.bindingHandlers['textWithDefault'] = {
    'init': function() {
      return { 'controlsDescendantBindings': true };
    },
    'update': function (element, valueAccessor) {
        var value, defaultValue;
        var options = ko.utils.unwrapObservable(valueAccessor());
        if (options !== null && typeof options == "object") {
            value = ko.unwrap(options['text']);
            defaultValue = ko.unwrap(options['default']);
        } else {
            value = options;
        }
        defaultValue = defaultValue || '-';

        ko.utils.setTextContent(element, value || defaultValue);
    }
};

function ExampleModel() {
  this.value = 'Sample text';
  this.observableValue = ko.observable('More sample text');
  this.emptyValue = '';
  this.emptyObservableValue = ko.observable();
};

ko.applyBindings(new ExampleModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<div data-bind="textWithDefault: value"></div>
<div data-bind="textWithDefault: observableValue"></div>
<div data-bind="textWithDefault: emptyValue"></div>
<div data-bind="textWithDefault: emptyObservableValue"></div>
<div data-bind="textWithDefault: { text: emptyValue, default: 'Custom empty value' }"></div>
<div data-bind="textWithDefault: { text: emptyObservableValue, default: 'Another custom empty value' }"></div>
1
Philip Bijker

Je suis tombé sur cela lors du retour de données pour une table, mais avec seulement quelques colonnes triables.

<tr data-bind="foreach: ArrAsrColumnHeaders">
  <th class="sortable koJson" data-bind="
     css: {active: ((typeof(isActive) != 'undefined') ?  isActive : '')}
      , text: text
      , attr:{href: ((typeof(jsonClick) != 'undefined') ?  jsonClick : '')}">
  </th>
</tr>

Cela signifie que, pour chaque colonne de l'en-tête du tableau, ajoutez la classe "active" si "isActive" est définie et définie sur true, mais ne paniquez pas si elle n'est pas là. Il en va de même pour l'ajout d'un attribut "href".

Avertissement: je ne comprends pas assez bien le knock-out pour connaître les limites de cette approche, mais cela a fonctionné pour moi dans mon cas, tandis que l'approche plus simple de css: {active: isActive() || ''} a généré des erreurs.

0
JJ Rohrer

Pour afficher les données dans le champ de saisie, le moyen le plus simple est ...

<input title="Stage" value="Default Entry Goes Here" readonly="readonly" type="text" id="stage" class="form-control" data-bind="value: model.stage ||text-input: Default Entry Goes Here">

Ça fait des erreurs mais ça marche .. :)

0
speed_racer