Knockout.js KnockoutJS-将对象推入可观察数组是';t数据绑定

Knockout.js KnockoutJS-将对象推入可观察数组是';t数据绑定,knockout.js,knockout-mapping-plugin,Knockout.js,Knockout Mapping Plugin,我的视图模型是一个带有场景的游戏,每个场景都有一些消息 视图模型是一个普通的JSON对象,它映射为可以通过映射插件观察到。整个应用程序工作正常,所有数据绑定和其他功能都正常工作。但是 我使用拖放将消息添加到场景中,因此我在侧面渲染了空消息(不包括在场景消息数组中,而是作为一个独立对象),在拖放拖动的消息时,我将其推送到场景消息可观察数组中,当我在我的游戏对象中查看时,我可以看到添加了一条新消息,但在ui中没有效果,假设我们从数组中的2条消息开始,它们在应用程序加载时呈现良好,现在我在数组中有3条

我的视图模型是一个带有场景的游戏,每个场景都有一些消息

视图模型是一个普通的JSON对象,它映射为可以通过映射插件观察到。整个应用程序工作正常,所有数据绑定和其他功能都正常工作。但是

我使用拖放将消息添加到场景中,因此我在侧面渲染了空消息(不包括在场景消息数组中,而是作为一个独立对象),在拖放拖动的消息时,我将其推送到场景消息可观察数组中,当我在我的游戏对象中查看时,我可以看到添加了一条新消息,但在ui中没有效果,假设我们从数组中的2条消息开始,它们在应用程序加载时呈现良好,现在我在数组中有3条消息,但ui中只显示2条

下面是一些代码:

这是拖放代码-

(function () {
        var _dragged;
        ko.bindingHandlers.drag = {
            init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
                var dragElement = $(element);
                var dragOptions = {
                    helper: 'clone',
                    appendTo: 'body',
                    revert: true,
                    revertDuration: 0,
                    start: function () {
                        _dragged = ko.utils.unwrapObservable(valueAccessor().value);
                    },
                    cursor: 'default'
                };
                dragElement.draggable(dragOptions).disableSelection();
            }
        };

        ko.bindingHandlers.drop = {
            init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
                var dropElement = $(element);
                var dropOptions = {
                    drop: function (event, ui) {
                        valueAccessor().value.push(ko.mapping.fromJS(_dragged));
                    }
                };
                dropElement.droppable(dropOptions);
            }
        };
    })();
这将使用drop来创建每个绑定的消息-

<div id="sceneMessages" data-bind="foreach: game.ContentScenes()[0].ContentMessages(), drop: { value: game.ContentScenes()[0].ContentMessages() }">
    <span data-bind="text: id"></span>
    <br />
</div>
这个JSON映射如下:

 var Scene = function (data){
        ko.mapping.fromJS(data,{},this);
        this.isCurrent = function(){
            return pageOptions.queryString("scene") == this.id();
        };
        this.url = function(){
            return _url + this.id();
        };
    }

 var mappingOptions = {
        'ContentScenes':{
            create:function(options){
                return new Scene(options.data);
            }
        },
        'ContentCharacters': {
            key: function(data) {
                return ko.utils.unwrapObservable(data.id);
            }
        }
    }

 var _gameJson = {

        game: ko.mapping.fromJS(_jsonObject,mappingOptions)
 }

  ko.applyBindings(_gameJson);

你知道我在做什么吗?

所以,当你初始化你的拖拽时,你只是在加载时评估世界的状态,而不是在元素更新时…例如,我实现了一个方法

ko.bindingHandlers.DragEmployee = {
    update: function (element, valueAccessor) {
        var dragElement = $(element);
        if (valueAccessor()) {

            dragElement.toggleClass('draggable', true);
            dragElement.kendoDraggable({
                hint: function(e) {
                    return $("<label class='grabbedObject' style='font-weight: bold;'>" + $(e).text() + "</label>");
                },
                cursorOffset: { top: -4, left: -20 },
                dragstart: function(e) { $(e.currentTarget).kendoAddClass('grabbed'); },
                dragend: function (e) { $(e.currentTarget).kendoRemoveClass('grabbed'); }
            });
        } else {
            if (dragElement.data('kendoDraggable')) {
                dragElement.toggleClass('draggable', false);
                dragElement.data('kendoDraggable').destroy();
            }
        }
    }

};
然后,当我想要获取绑定到此元素的数据时

ko.dataFor(e.draggable.element[0])

砰……然后我就可以访问我绑定的整个模型了。

好吧,感谢KnockoutJS的“方便”语法,我花了一段时间才注意到它

以下是一段引述:

语法更方便。要调用KO的push方法,只需编写 myObservableArray.push(…)。这比打电话给 通过写入底层数组的push方法 myObservableArray().push(…)


这意味着,当你想将一个对象添加到数组中时,你不能以正常和直观的方式通过读取对象获取数组并按如下方式推到它:myArray().push(obj),你应该获取可观察对象并按如下方式推到对象:myArray.push(obj)。太棒了

不幸的是,这不是我的问题,更新并不能解决我的问题。我写的代码是这把小提琴的复制品:它工作得很好(看看我上面的编辑)
ko.bindingHandlers.DragEmployee = {
    update: function (element, valueAccessor) {
        var dragElement = $(element);
        if (valueAccessor()) {

            dragElement.toggleClass('draggable', true);
            dragElement.kendoDraggable({
                hint: function(e) {
                    return $("<label class='grabbedObject' style='font-weight: bold;'>" + $(e).text() + "</label>");
                },
                cursorOffset: { top: -4, left: -20 },
                dragstart: function(e) { $(e.currentTarget).kendoAddClass('grabbed'); },
                dragend: function (e) { $(e.currentTarget).kendoRemoveClass('grabbed'); }
            });
        } else {
            if (dragElement.data('kendoDraggable')) {
                dragElement.toggleClass('draggable', false);
                dragElement.data('kendoDraggable').destroy();
            }
        }
    }

};
$(e.draggable.element[0])
ko.dataFor(e.draggable.element[0])