Ответ 1
При использовании наблюдаемого в выражении вам нужно получить к нему доступ как функцию:
visible: !charted()
Я хотел бы использовать свойство на моем ViewModel, чтобы переключать отображение этого значка без создания отдельного вычисленного свойства обратного. Возможно ли это?
<tbody data-bind="foreach: periods">
<tr>
<td>
<i class="icon-search" data-bind="visible: !charted, click: $parent.pie_it"></i>
<i class="icon-remove" data-bind="visible: charted, click: $parent.pie_it"></i>
</td>
</tr>
</tbody>
My ViewModel имеет периоды свойств, которые являются массивом месяца, например:
var month = function() {
this.charted = ko.observable(false);
};
При использовании наблюдаемого в выражении вам нужно получить к нему доступ как функцию:
visible: !charted()
Я согласен с комментарием Джона Папы, что должно быть встроенное связывание hidden
. Для выделенной привязки hidden
существует два преимущества:
hidden: charted
вместо visible: !charted()
.charted
напрямую, а не создавать computed
для наблюдения !charted()
.Это достаточно просто, чтобы создать привязку hidden
, но вот так:
ko.bindingHandlers.hidden = {
update: function(element, valueAccessor) {
ko.bindingHandlers.visible.update(element, function() {
return !ko.utils.unwrapObservable(valueAccessor());
});
}
};
Вы можете использовать его так же, как встроенная привязка visible
:
<i class="icon-search" data-bind="hidden: charted, click: $parent.pie_it"></i>
<i class="icon-remove" data-bind="visible: charted, click: $parent.pie_it"></i>
Это немного запутывает, как вам нужно делать
visible:!showMe()
Итак, я сделал
<span data-bind="visible:showMe">Show</span>
<span data-bind="visible:!showMe()">Hide</span>
<label><input type="checkbox" data-bind="checked:showMe"/>toggle</label>
моя модель
var myModel={
showMe:ko.observable(true)
}
ko.applyBindings(myModel);
check in fiddle http://jsfiddle.net/khanSharp/bgdbm/
Вы можете использовать привязку switch/case, которая включает case.visible
и casenot.visible
.
<tbody data-bind="foreach: periods">
<tr>
<td data-bind="switch: true">
<i class="icon-search" data-bind="case.visible: $else, click: $parent.pie_it"></i>
<i class="icon-remove" data-bind="case.visible: charted, click: $parent.pie_it"></i>
</td>
</tr>
</tbody>
Вы также можете использовать его как
<i class="icon-search" data-bind="casenot.visible: charted, click: $parent.pie_it"></i>
<i class="icon-remove" data-bind="case.visible: $else, click: $parent.pie_it"></i>
Чтобы сделать привязку осведомленной об изменениях свойства, я скопировал видимый обработчик привязки и перевернул его:
ko.bindingHandlers.hidden = {
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var isCurrentlyHidden = !(element.style.display == "");
if (value && !isCurrentlyHidden)
element.style.display = "none";
else if ((!value) && isCurrentlyHidden)
element.style.display = "";
}
};
Отказ от ответственности: это решение предназначено только для развлекательных целей.
ko.extenders.not = function (target) {
target.not = ko.computed(function () {
return !target();
});
};
self.foo = ko.observable(true).extend({ not: null });
<div data-bind="text: foo"></div> <!-- true -->
<div data-bind="text: foo.not"></div> <!-- false -->
<!-- unfortunately I can't think of a way to be able to use:
text: foo...not
-->
У меня была такая же проблема, как использовать противоположность логического наблюдаемого. Я нашел легкое решение:
var ViewModel = function () {
var self = this;
// When program start, this is set to FALSE
self.isSearchContentValid = ko.observable(false);
self.gatherPlacesData = function () {
// When user click a button, the value become TRUE
self.isSearchContentValid(true);
};
Теперь на вашем HTML вы должны сделать это
<p data-bind = "visible:isSearchContentValid() === false"> Text 1</p>
<p data-bind = "visible:isSearchContentValid"> Text 2</p>
Когда программа запускается, отображается только "Text1", потому что "false === false is TRUE", а Text2 не отображается.
Допустим, у нас есть кнопка, которая вызывает команду gatherPlacesData при клике. Теперь Text1 не будет виден, потому что "true === false is FALSE" и текст 2 будет только видимым.
Другим возможным решением может быть использование вычисленных наблюдаемых, но, я думаю, это сложное решение для столь простой задачи.
Также можно использовать скрытый, например:
<div data-bind="hidden: isString">
<input type="text" class="form-control" data-bind="value: settingValue" />
</div>