2013-06-05 14 views
9

Mam prosty model widoku z kilkoma wymaganymi atrybutami ... Chcę, aby każde wejście podświetlało kolor czerwony, jeśli odpowiednia właściwość nie jest poprawna, ale nie chcę, aby to podświetlenie było wyświetla się, gdy strona jest początkowo ładowana ... tylko wtedy, gdy zmienia się wartość lub gdy użytkownik próbuje zapisać/kontynuować ...Zapobieganie sprawdzaniu nokautu od oceny przy początkowym obciążeniu

Teraz sprawdza poprawność modelu widoku podczas początkowego obciążenia, ponieważ określam powiązanie danych = "css: {error: name.isValid() == false}", ale nie znam żadnego innego sposobu, aby to działało dynamicznie (podobnie jak działa sprawdzająca poprawność jQuery) ...

var foo = { name: ko.observable().extend({required: true}) }; 

<div data-bind="css: { error: !name.isValid() }"> 
    <input type="text" data-bind="value: name" /> 
</div> 

Wszelkie pomysły na to, jak wykonać tę pracę, zostaną docenione ... Dzięki!

Odpowiedz

2

Więc tutaj jest rozwiązanie wymyśliłem:

var Foo = function() 
{ 
    this.name = ko.observable().extend({required: true}).isModified(false); 
    this.validate: function() 
    { 
     if (!this.isValid()) 
     { 
      //... loop through all validated properties and set .isModified(true) 
      return false; 
     } 
     return true; 
    }; 
    ko.validation.group(foo); 
}; 

var Bar = function() 
{ 
    this.foo = new Foo(); 
    this.errors = ko.observableArray([]); //<-- displays errors for entire page 
    this.save = function() 
    { 
     if (!this.foo.validate()) 
     { 
      this.errors(ko.toJS(this.foo.errors())); 
     } 
    }; 
} 

ko.applyBindings(new Bar()); 

A oto znaczniki ...

<div data-bind="with: foo"> 
    <div class="control-group" 
     data-bind="css: { error: name.isModified() && !name.isValid() }"> 
     <label class="control-label">Name<span class="help-inline">*</span></label> 
     <div class="controls"> 
      <input type="text" class="input-block-level" placeholder="Name" 
        data-bind="value: name, event: { blur: function() { name.isModified(true); }}" /> 
     </div> 
    </div> 

    <div class="alert alert-error" 
     data-bind="visible: $parent.errors().length > 0"> 
     <h5>Errors!</h5> 
     <ul data-bind="foreach: $parent.errors()"> 
      <li data-bind="text: $data"></li> 
     </ul> 
    </div> 
</div> 

<button type="submit" class="btn btn-primary" data-bind="click: save">Save</button> 

i tu jest CSS

.error { color: Red; font-weight: bold; } 
.help-inline { display: none; } 
.error .help-inline { display: inline-block; } 
.error input { border-color: Red; } 
5

Lepszym rozwiązaniem jest skonfigurowanie sprawdzania poprawności nokautu w celu udekorowania elementu za pomocą klasy validationElement. Odbywa się to poprzez dodanie tej opcji konfiguracji:

ko.validation.configure({ decorateElement: true }); 

Click here to see a jsfiddle demonstrating this.

**** EDIT, w odpowiedzi na komentarz z pytań Pytający ***

Jeśli chcesz ozdobić elementu nadrzędnego, bardziej eleganckim i wielokrotnego użytku rozwiązaniem jest zastosowanie tego niestandardowego powiązania z elementem nadrzędnym.

JavaScript

ko.bindingHandlers.parentvalElement = { 
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var valueIsValid = valueAccessor().isValid(); 
     if(!valueIsValid && viewModel.isAnyMessageShown()) { 
      $(element).addClass("parentError"); 
     } 
     else { 
      $(element).removeClass("parentError"); 
     } 
    } 
}; 

i zastosować wiązania w kodzie HTML tak:

<form data-bind='submit:OnSubmit'> 
    <label data-bind='parentvalElement:name'> 
     <span>Name</span> 
     <input data-bind="value: name" /> 
    </label> 
    <input type='submit' value='submit' /> 
<form> 

Spójrz at this updated jsfiddle to see it in action.

+0

Niestety, w moim dążeniu do uproszczenia moim przykładem, wyszedłem na zewnątrz, że jestem w rzeczywistości dekorowanie elementu div rodzicem za pomocą klasy "error", a nie samego elementu wejściowego, ponieważ istnieją inne elementy potomne/elementy rodzeństwa, które również wymagają zmiany (np. kolor etykiety i "*" widoczność zakresu), więc to nie zadziała dla mnie jednak myślę, że wymyśliłem sposób, aby to osiągnąć plish to ... zasadniczo, dołączam .isModified (false) po każdym wywołaniu .extend(), a następnie sprawdzam, czy .isModified() w mojej logice wiążącej css (patrz poniżej ...) –

+0

Dołączyłem moją odpowiedź z prostsze i bardziej powtarzalne rozwiązanie udekoruj element nadrzędny .... wypróbuj go! – RodneyTrotter

+0

Udało mi się uruchomić go bez konieczności tworzenia programu obsługi wiążącej ... Jedyną częścią, której nie lubię w moim rozwiązaniu, jest to, że muszę ręcznie przeglądać właściwości modelu widoku i ustawić wartość isModified (true)), aby nieprawidłowe, ale niezmodyfikowane pola pokazywały swój stan błędu, gdy mój zewnętrzny obiekt wywoływał .save(). –

Powiązane problemy