Knockout.js Шаблон не обновляет привязку пользовательского интерфейса для зависимого объекта - PullRequest
2 голосов
/ 20 мая 2011

Приложение написано с использованием ASP.NET MVC 3 в vs2010.

У меня есть шаблон выбивки, который обновляет некоторые CSS и видимые привязки с использованием depenndantObservable.

Проблема возникает ТОЛЬКО, когда я связываю значение элемента select с IntervalID.Если это не связано, пользовательский интерфейс обновляется, как и ожидалось.

Я извлек код из моего основного приложения и создал образец страницы, которая выполняет такую ​​же привязку, используя стандартную разметку и шаблоны.

Зависимый объект Observable называется HasChanged.

 <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="../../Scripts/jquery.tmpl.js" type="text/javascript"></script>
<script src="../../Scripts/knockout-1.2.0.js" type="text/javascript"></script>

<div data-bind="template: { name: 'intervalTemplate', for:viewModel }">
</div>
<h2>
    Not Template</h2>
<div data-bind="style: { color: HasChanged() ? 'red' : 'black' }">
    IntervalID: <span data-bind="text: IntervalID"></span>
    <br />
    Start:
    <input type="text" data-bind="value: Start">
    <br />
    End:
    <input type="text" data-bind="value: End">
    <br />
    Interval Type:
    <select data-bind="value: IntervalTypeID">
        <option value="1">Shift</option>
        <option value="2">Break (Paid)</option>
        <option value="3">Break (Unpaid)</option>
    </select><br />
    HasChanged: <span data-bind="text: HasChanged"></span>
</div>

<script id="intervalTemplate" type="text/html">
    <div data-bind="style: { color: HasChanged() ? 'red' : 'black' }">
    <h2>Template</h2>
IntervalID: <span data-bind="text: IntervalID"></span>
<br />
Start:
<input type="text" data-bind="value: Start">
<br />
End:
<input type="text" data-bind="value: End">
<br />
Interval Type:
<select data-bind="value: IntervalTypeID">
    <option value="1">Shift</option>
    <option value="2">Break (Paid)</option>
    <option value="3">Break (Unpaid)</option>
</select><br />
HasChanged: <span data-bind="text: HasChanged"></span>
</div>
</script>

<script type="text/javascript">
    function IntervalModel(data) {
        var _this = this;

        _this.IntervalID = ko.observable(data.IntervalID);
        _this.Start = ko.observable(data.Start);
        _this.End = ko.observable(data.End);
        _this.IntervalTypeID = ko.observable(data.IntervalTypeID);

        _this.OriginalStart = ko.observable(data.Start);
        _this.OriginalEnd = ko.observable(data.End);
        _this.OriginalIntervalTypeID = ko.observable(data.IntervalTypeID);


        _this.HasChanged = ko.dependentObservable(function () {
            return !(_this.OriginalStart() == _this.Start() &
                _this.OriginalEnd() == _this.End() &
                _this.OriginalIntervalTypeID() == _this.IntervalTypeID());
        });

    }

    var viewModel;

    $(function () {

        var viewModel = {};

        viewModel = new IntervalModel({ IntervalID: 1, Start: "09:00", End: "10:00", IntervalTypeID: 2 });
        ko.applyBindings(viewModel);

    });

</script>

Любая помощь будет принята с благодарностью ... Мне нужно использовать шаблоны, так как у меня есть много этих интервалов, которые должны отображаться.

Спасибо!

1 Ответ

4 голосов
/ 20 мая 2011

Существует проблема, зарегистрированная на github для этого здесь: https://github.com/SteveSanderson/knockout/issues/133

Проблема сосредоточена вокруг использования чисел для значения опции выбора.Когда элемент select использует привязку value, он обновляется фактическим значением элемента, которое всегда является строкой.Таким образом, если ваша наблюдаемая равна 2, она устанавливается на «2» при настройке привязки.Похоже, что это изменение вызывает проблему с любыми привязками, которые используют ту наблюдаемость, которая была установлена ​​в шаблоне до элемента select.

Таким образом, пока это не будет исправлено, вы можете заставить его работать, передавая IntervalTypeID какстрока («2»).Простой способ преобразовать число в строку - это сделать yourvalue + ''.

Вот оно: http://jsfiddle.net/rniemeyer/uDSFa/

...