2013-08-12 5 views
0

Я использую нокаут, и я спокоен к нему, у меня есть определенное условие, в котором я должен определить некоторые свойства только для чтения в моей модели.Как сделать readonly свойство в нокауте

и позже я хочу проверить состояние/состояние свойства, что поле доступно только для чтения или нет.

Я искал часы в Google, но не нашел подходящего решения. я нахожу это fiddle.

var ViewModel = function() { 
var self = this; 
self.getDisabledState = ko.observable(null); 
self.getreadonlyState = ko.observable(null); 
self.enable = function() { 
    if (self.getDisabledState()) self.getDisabledState(undefined); 
    else self.getDisabledState('disabled'); 
} 
self.readonly = function() { 
    if (self.getreadonlyState()) self.getreadonlyState(undefined); 
    else self.getreadonlyState('readonly'); 
    } 
} 

ko.applyBindings(new ViewModel()); 

Так что интересно, помог ли кто-нибудь мне.

Заранее благодарен.

+0

Что не в порядке с посланной скрипку? – Damien

+0

Возможный дубликат [привязки нокаута attr с такими атрибутами, как «readonly» и «disabled»] (http://stackoverflow.com/questions/14165213/knockout-attr-binding-with-attributes-like-readonly-and-disabled) – bummi

ответ

-1

Вы можете использовать enable привязки, чтобы установить элемент для инвалидов, как в данном примере, она хорошо работает для элементов формы, таких как ввод, выберите текстовое поле и .:

<p> 
    <input type='checkbox' data-bind="checked: hasCellphone" /> 
    I have a cellphone 
</p> 
<p> 
    Your cellphone number: 
    <input type='text' data-bind="value: cellphoneNumber, enable: hasCellphone" /> 
</p> 

<script type="text/javascript"> 
    var viewModel = { 
    hasCellphone : ko.observable(false), 
    cellphoneNumber: "" 
}; 
</script> 

Нокаут документация: http://knockoutjs.com/documentation/enable-binding.html

Позже, если вы хотите проверить статус своего элемента, просто прочитайте значение наблюдаемого hasCellphone().

+0

Спасибо, это решение может работать, и я думаю, что мы всегда должны стараться предпочитать рекомендуемый способ. Еще раз спасибо – Ancient

+2

Он попросил свойство readonly, это только отключает ввод. – Anders

+0

Проблема с отключением ввода заключается в том, что IE имеет особый способ стилизации отключенных входов, которые нельзя переопределить. Однако входы, доступные для чтения, могут быть стилизованы, что делает его более желательным. –

4

Немного расширитель я просто написал

http://jsfiddle.net/cpsct/

ko.extenders.readonly = function(target, readonly) { 
    var computed = ko.computed({ 
     read: target, 
     write: function(value) { 
      if(!computed.canWrite()) 
       throw "Observable in read only mode" 

      target(value); 
     } 
    }); 

    computed.canWrite = ko.observable(!readonly); 
    return computed; 
}; 

обновление: Если его образец охранник вы после того, как я рекомендую посмотреть в моем Lib Knockout.BindingConventions

Пример http://jsfiddle.net/QzZPg/2/ (Запись отключена в текстовом поле)

+0

может помочь мне немного дальше, я попытался написать во втором текстовом поле, это не только для чтения. Я могу писать в нем. – Ancient

+0

Звучало так, что вы хотели видеть наблюдаемое (свойство), которое было только что прочитано, помеченный ответ не помешает viewmodel или другому коду обновить значение только в представлении – Anders

1
html code: 
    <input type="text" data-bind="value:SkuAttributeValue1,readOnly: IsAudit" class="form-control" /> 
knockoutjs code: 
    function ProductSkuItemModel(item) { 
var self = this; 
self.SkuAttributeValue1 = ko.observable(item.SkuAttributeValue1); 
self.SkuAttributeValue2 = ko.observable(item.SkuAttributeValue2); 
self.ProductSkuId = ko.observable(item.ProductSkuId); 
self.SkuAttributeValue =ko.observable(skuAttributeName1 + ":" +  item.SkuAttributeValue1 + " " + skuAttributeName2 + ":" + item.SkuAttributeValue2); 
self.IsAudit = ko.observable(false); 
     } 
    ko.bindingHandlers.readOnly = { 
      update: function(element, valueAccessor) { 
       var value = ko.utils.unwrapObservable(valueAccessor()); 
       //alert(value); 

       if (!value) { 
        element.setAttribute("readOnly", true); 
       } else { 
        element.removeAttribute("readOnly"); 
       } 
      } 
     }; 
8

Хотя ответ Маурицио правильно в том, что вы должны связать логическое значение из модели представления, что отключает вход, одну потенциальную проблему с помощью «включить» связывание может быть то, что стили Internet Explorer отключены входы в своем роде и не позволяет вам изменить этот стиль. Это может привести к отключенным входам, которые едва различимы.

Чтобы исправить это, мы создали специальный обработчик привязки, который вместо этого устанавливает флаг readonly и добавляет определенный стиль. Это отключает ввод и позволяет нам стилизовать его по-своему.

Это CSS стиль, мы добавили:

input.disabled 
{ 
    border: 1px solid #888; 
    color: #888; 
    height: 22px !important; 
    padding: 2px; 
} 

И это обычай привязки обработчика, состоявшейся в общем Js файл:

ko.bindingHandlers.readonly = { 
    update: function (element, valueAccessor) { 
     if (valueAccessor()) { 
      $(element).attr("readonly", "readonly"); 
      $(element).addClass("disabled"); 
     } else { 
      $(element).removeAttr("readonly"); 
      $(element).removeClass("disabled"); 
     } 
    } 
}; 

Тогда это просто вопрос применения связывания в HTML, как это:

<input type="text" data-bind="value: MyValue, readonly: MyBoolean" /> 
+0

Кажется, мне пришлось вызвать unrapObservable на valueAccessor(), чтобы получить эту работу. –

+1

Возможно, это зависит от того, на что вы действительно привязаны, или как вы настроили привязку в представлении. Похоже, вы каким-то образом привязаны к наблюдаемому свойству, а не к его ценности. –

3

Вы можете использовать этот binginHandlers:

ko.bindingHandlers.readOnly = { 
    update: function (element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     if (value) { 
      element.setAttribute("disabled", true); 

     } else { 
      element.removeAttribute("disabled"); 
     } 
    } 
}; 

В моем HTML:

<input type="text" id="create-finess" class="form-control" data-bind="readOnly: _locked" /> 

Finaly в моих JS:

//Constructor of my view model 

    function ViewModel(resx) { 
     this._locked = ko.observable(); 
} 

    // on init of the page i lock the input 
this._load = function() { 
    this._locked(true); 
}