Видимая привязка Knockout.js во вложенном контейнере не получает видимого значения - PullRequest
0 голосов
/ 08 января 2019

У меня есть небольшое приложение 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. Похоже, что привязка каким-то образом вычисляется после рендера, поскольку щелчок для редактирования корректно отключает интервал, но явно что-то не так.

...