2 votes

Knockout select et textbox sharing binding

J'ai une page avec un select et un input-box liés à la même valeur. L'idée est que l'on devrait normalement sélectionner une valeur à partir de la sélection, mais l'utilisateur devrait également être en mesure d'entrer une chaîne arbitraire dans la boîte de saisie. Le problème est que si j'entre quelque chose qui n'est pas présent dans la sélection, à cause de la liaison, la valeur est fixée au premier élément de la sélection.

C'est le comportement que je veux obtenir :

L'utilisateur sélectionne une valeur à partir d'une sélection

  1. La valeur est réglée sur l'élément sélectionné.
  2. L'entrée est mise à jour avec la valeur sélectionnée.

L'utilisateur saisit du texte dans l'entrée

  1. La valeur est fixée au texte saisi.
  2. La sélection ne change pas sauf si La valeur est présente dans la collection des valeurs disponibles.

En d'autres termes, ce que je veux, c'est que le dernier contrôle modifié soit la valeur valide. Mais je veux aussi que les deux contrôles soient à jour tant qu'une valeur donnée est valable pour ce contrôle .

Mon code ressemble à ceci :

js

var viewModel = { Value: ko.observable('1'), Set: ['1', '2', '3'] };
ko.applyBindings(viewModel);

html

<!-- ko if: Set.length > 1 || (Set.length > 0 && Set[0] != '') -->
<select type="text" class="form-control input-small" data-bind="options: Set, value: Value">
</select>
<!-- /ko -->

<input class="form-control input-small" data-bind="value: Value" style="margin-top: 5px;" />

Voici un jsfiddle qui montre comment le code fonctionne actuellement : http://jsfiddle.net/b2RwG/

[Editer]
J'ai trouvé une solution qui fonctionne ( http://jsfiddle.net/b2RwG/2/ ), mais ce n'est vraiment pas joli, et il doit y avoir une meilleure façon de résoudre ce problème.

1voto

Damien Points 5330

Comme vous pouvez le voir, j'ajoute un observable inputValue qui est lié à l'entrée texte. J'ajoute également un calcul nommé virtualSet qui contient à la fois les éléments originaux et le nouvel élément (provenant de l'entrée de texte). Je susbcribe à l'observable inputValue pour que la sélection soit automatiquement définie lorsque vous tapez.

var viewModel = {    
    inputValue: ko.observable('1'),
    Value: ko.observable('1'),
    Set: ['1', '2', '3']    
};
viewModel.virtualSet = ko.computed({
    read: function () {
        var vs = this.Set.slice(0);
        if (this.inputValue() && this.inputValue().length)
             vs.unshift(this.inputValue());
        return vs;
    },
    owner: viewModel
});
viewModel.inputValue.subscribe(function (value) {
    viewModel.Value(value);
});

Voir violon

J'espère que cela vous aidera.

0voto

dan.p Points 396

Vous pouvez faire en sorte que la sélection utilise plutôt un observable calculé, qui n'est mis à jour que si la valeur a un sens.

J'ai réalisé un exemple dans lequel j'ai ajouté une légende à la sélection. Le résultat est qu'il ne choisit pas automatiquement la première valeur, mais essaie de définir une valeur indéfinie, lorsqu'il lit une valeur qui n'est pas incluse dans l'élément Set de la gamme.

<select type="text" class="form-control input-small" data-bind="options: Set, value: SelectValue, optionsCaption: 'Other value'"></select>

Pour ce faire, il est plus facile d'utiliser une fonction de construction plutôt qu'un littéral d'objet, car vous pouvez alors accéder à l'élément Value observable par l'intermédiaire de la self référence.

function ViewModel() { 
    var self=this; 
    this.Value = ko.observable('1'); 
    this.Set = ['1', '2', '3']; 
    this.SelectValue= ko.computed({
                 read: function() {
                     var val = self.Value(); 
                     return val; 
                 }, 
                 write: function(value) {
                     if(value) self.Value(value); 
                 }
    });
}

Véase http://jsfiddle.net/b2RwG/4/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X