My view model is a game with scene and each scene have some messages.
The view model was a plain JSON object that mapped to be observable with the mapping plugin. The whole app is working fine, all data binding and other features are working as accepted. but...
I'm using drag and drop in order the add messages to scene so I've rendered empty messages at the side (not included in the scene messages array but as a stand alone object) and when dropping the dragged message I've took it pushed it to the scene messages observable array, and when I'm looking in my game object I can see that a new message has been added but there is no effect in the ui, lets say we started with 2 messages in the array and they rendered fine in the load of the app, now I have 3 messages in the array but only 2 are shown in the ui.
Here are some pieces of the code:
This is the drag and drop code -
(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);
}
};
})();
This the messages foreach binding with the 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>
And this is the empty new messages with the drag -
<ul data-bind="foreach: messagesTypes">
<li data-bind="text: MessageType.name, drag: { value: $data }"></li>
</ul>
Any idea what I'm doing worng? could it be because of the mapping plugin?! as I mentioned the new message is added to the array properly.
EDIT:
Actually, I've just realized that even a simple push without the drag and drop isn't working as accepted..
the JSON from the server is looks something like that:
"ContentScenes": [
{
"ContentMessages": [
{
"PrivateMessageType": null,
"MessageType": {
"id": 1,
"name": "Public"
},
"id": 7,
"scene_id": 3,
"parent_id": null,
"time_offset": null,
"from": null,
"to": null,
"msg_type": 1,
"is_system": true
},
{
"PrivateMessageType": null,
"MessageType": {
"id": 1,
"name": "Public"
},
"id": 8,
"scene_id": 3,
"parent_id": null,
"time_offset": null,
"from": null,
"to": null,
"msg_type": 1,
"is_system": true
}
],
"ContentResources": [],
"id": 3,
"game_id": 28,
"name": null,
"discussion_duration": null,
"break_duration": null,
"vote_duration": null,
"is_template": true
},
{
"ContentDilemmaOptions": [],
"ContentMessages": [],
"ContentResources": [],
"id": 4,
"game_id": 28,
"name": null,
"discussion_duration": null,
"break_duration": null,
"vote_duration": null,
"is_template": false
}
],
"id": 28,
"mainImage": null,
"sideImage": null,
"description": "Game description",
"name": "Game Name",
"locale": null
And this JSON is mapped like this:
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);
So, any idea what I'm doing worng?