0

私はこれに関するすべての関連記事を読み、過去 2 日間、ここで何が間違っているのかを理解しようとしましたが、あまり成功しませんでした。

例として、この JS フィドルを使用します: http://jsfiddle.net/rniemeyer/dtpfv/ダーティ フラグを実装しようとしています。唯一の違いは、通常のスパンと入力フィールド内のデータを変更し、マッピング プラグインと手動でオブザーバブルを割り当てることです。

$(document).ready(function(){

    ko.dirtyFlag = function(root, isInitiallyDirty) {
        var result = function() {},
            _initialState = ko.observable(ko.toJSON(root)),
            _isInitiallyDirty = ko.observable(isInitiallyDirty);

        result.isDirty = ko.computed(function() {
            return _isInitiallyDirty() || _initialState() !== ko.toJSON(root);
        });
        result.reset = function() {
            _initialState(ko.toJSON(root));
            _isInitiallyDirty(false);
        };
        return result;

    };

    $.getJSON('/environments/data.json', function(jsondata) {
        var mapping = {
            create: function (options) {
                var innerModel = ko.mapping.fromJS(options.data);
                for (var i=0; i < innerModel.deployments().length; i++) {
                    innerModel.deployments()[i].dirtyFlag = new ko.dirtyFlag(innerModel.deployments()[i]);
                }
                return innerModel;
            }
        }

        var viewModel = ko.mapping.fromJS(jsondata, mapping);

        self.save = function() {
            console.log("Sending changes to server: " + ko.toJSON(this.dirtyItems));  
        };

        self.dirtyItems = ko.computed(function() {
            for (var i = 0; i < viewModel().length;  i++ ) {
                return ko.utils.arrayFilter(viewModel()[i].deployments(), function(deployment) {
                    return deployment.dirtyFlag.isDirty();
                });
            }
        }, viewModel);

        self.isDirty = ko.computed(function() {
            return self.dirtyItems().length > 0;
        }, viewModel);

        self.changeTag = function (data, event) {

            // Neither .change() nor .trigger('change') work for me
            $(event.target).parents().eq(4).find('span.uneditable-input').text(data.tag).change()

            // This value never changes.
            console.log('Dirty on Change: '+self.dirtyItems().length)

        }

        ko.applyBindings(viewModel);

    });

})

これは、関数をトリガーする HTML の一部を取り除いたもので、ドロップダウン メニューからの選択changeTag()に置き換えられます。current_tag()ただし、これは KnockoutJS の更新をトリガーしません。

<div>
    <span data-bind="text: current_tag() }"></span>
    <div>
        <button data-toggle="dropdown">Select Tag</button>
        <ul>
          <!-- ko foreach: $.parseJSON(component.available_tags() || "null") -->
          <li><a href="#" data-bind="click: function(data, event) { changeTag(data, event) }"></a></li>
          <!-- /ko -->
        </ul>
    </div>
</div>

私はこれを理解しようとして2日目です。私がここで間違っていることは何か分かりますか? 通常のスパン要素ではなく、入力フィールドを使用する必要がありますか? viewModeljQuery を使用して DOM を操作する代わりに、値を直接変更する必要がありますか? (私は実際にそれを試しましたが、変更viewModelしてから再バインドすると、間違っていない限り、速度が低下するようです)

ありがとうございました。

4

1 に答える 1