У меня есть небольшое приложение knockout.js / electronic, использующее в основном вложенные контейнеры. У меня возникла проблема, когда виджет, который можно щелкнуть для редактирования (извлечен из https://knockoutjs.com/documentation/hasfocus-binding.html Пример 2), не получает наблюдаемое логическое значение.
Следующее базовое приложение:
<div id="experiments" data-bind="foreach: experiments">
<experiment params="days: $data, base: $parent, index: $index"></experiment>
<hr/>
</div>
Со следующими привязками:
function BaseView() {
this.experiments = _ko.observableArray([]);
this.addExperiment = function() {
this.experiments.push([]);
};
}
var baseElement = document.getElementById('container');
baseElement.innerHTML = _fs.readFileSync(_app.getAppPath() +
_ko.applyBindings(new BaseView());
Экспериментальный компонент:
<div class="experiment-container">
<div class="experiment-input">
<div class="experiment-selector" data-bind="if: expEditing">
<select data-bind="options: dayTypes, value: selectedDay"></select>
<button data-bind="click: addDay">ADD</button>
</div>
<div class="experiment-viewer">
<div class="experiment-gutter">
<div class="days" data-bind="foreach: queueOfDays">
<day-widget params="day: $data"></day-widget>
</div>
</div>
</div>
</div>
</div>
Со следующей (усеченной) моделью вида:
_ko.components.register('experiment', {
viewModel: function(params) {
this.selectedDay = _ko.observable();
this.dayTypes = params.base.dayProfiles;
this.queueOfDays = _ko.observableArray(params.days);
this.addDay = function(_, event) {
if (this.queueOfDays().length > 0
&& this.queueOfDays()[this.queueOfDays().length - 1].type === this.selectedDay())
{
this.queueOfDays()[this.queueOfDays().length - 1].count(
this.queueOfDays()[this.queueOfDays().length - 1].count() + 1);
} else {
this.queueOfDays.push(makeDay());
}
setTimeout(function() {
scrollToEnd(event);
}, 50);
}.bind(this);
var scrollToEnd = function(event) {
var outElement = getParentWithClass(event.target, 'experiment-container')
.getElementsByClassName('days')[0];
outElement.scrollLeft = outElement.scrollWidth - outElement.clientWidth;
};
var makeDay = function() {
return {
type: this.selectedDay(),
count: _ko.observable(1)
};
}.bind(this);
},
template: getView('experiment.html')
});
И, наконец, моя проблема: виджет дня имеет следующий шаблон:
<span data-bind="visible: notEditMode, text: dayCount, click: turnOnEditMode"></span>
<input data-bind:"visible: editMode, value: dayCount, hasFocus: editMode"/>
Со следующей моделью:
_ko.components.register('day-widget', {
viewModel: function(params) {
this.dayCount = params.day.count;
this.editMode = _ko.observable(false);
this.notEditMode = _ko.computed(function() {
return !this.editMode();
}, this);
this.turnOnEditMode = function() {
this.editMode(true);
};
this.shortText = _ko.computed(function() {
return params.day.type + " x" + params.day.count();
}, this);
},
template: getView('day_widget.html')
});
ПРОБЛЕМА ЕСТЬ - когда вызывается addDay в эксперименте, создается виджет дня, изначально виджет дня отображается с видимыми элементами span и input. Похоже, что привязка каким-то образом вычисляется после рендера, поскольку щелчок для редактирования корректно отключает интервал, но явно что-то не так.