Knockout ko.mappings.fromJS not working - javascript

I am trying to use knockout mapping, but it isn't working as I expected.
Here I created simpliest fiddle i can and it's not working.
Am I missing something?
https://jsfiddle.net/p48d11j5/1/
function Model(){
var self = this;
self.Id = ko.observable(0);
self.Name = ko.observable("Default");
self.Visible = ko.observable(false);
self.Items = ko.observableArray([]);
}
function ModelItem(){
var self = this;
self.Id = ko.observable(0);
self.Name = ko.observable("Default item name")
}
var m = new Model();
ko.mapping.fromJS({
Id:1,
Name: "Test",
Visible: true,
Items: [
{
Id:1,
Name:"First"
},
{
Id:2,
Name:"Second"
}
]
}, m);
ko.applyBindings(m);
edit: I am working with nested arrays, so I added array
edit2: I want have models "typed" to use functions or ko.computed properties of them

If you call ko.mapping.fromJS with two arguments : ko.mapping.fromJS(data, mappedObject) the second argument is a mappedObject which is already created.Then the second argument will be taken as a viewModel not options.
All you have to do is: ko.mapping.fromJS(data, {}, viewModel) - this one puts your data in your model.
ko.mapping.fromJS({
Id:1,
Name: "Test",
Visible: true,
Items: [{Id: 1, Name: "First"}, {Id: 2, Name: "Second"}]
}, {} ,m); // pass the second argument as an empty object.

Try this
var m = ko.mapping.fromJS({
Id:1,
Name: "Test",
Visible: true,
Items: [
{
Id:1,
Name:"First"
},
{
Id:2,
Name:"Second"
}
]
}, new Model());
ko.applyBindings(m);
Working Example: https://jsfiddle.net/p48d11j5/2/

You can give something like this a try, using the mapping plugin to set up your default state as well as to apply updates:
// Set up the initial model.
var model = ko.mapping.fromJS({
Id: 0,
Name: "Default",
Visible: false,
Items: []
});
ko.applyBindings(model);
// Map new data from the "server"...
var model = ko.mapping.fromJS({
Id:1,
Name: "Test",
Visible: true,
Items: [
{
Id:1,
Name:"First"
},
{
Id:2,
Name:"Second"
}
]
}, model);
// ...or directly manipulate the model.
model.Id(2);
model.Items.push({Id: 3, Name: "Third"});
https://jsfiddle.net/3evtx022/

Related

VueJs How to duplicate object from v-repeat?

Functionality allows you to add/delete description, title and time for the event.
I can not deal with the duplication(cloning) of the object which is created through v-model = (event.name, event.description and event.date)
All works fine with the removing selected object, it works like this:
deleteEvent: function(index){
if(confirm('Are you sure?')) {
this.events.$remove(index);
}
}
Here's an example of my code for a application to adding and changing events.
var vm = new Vue({
el: '#events',
data:{
event: { name:'', description:'', date:'' },
events: []
},
ready: function(){
this.fetchEvents();
},
methods: {
fetchEvents: function() {
var events = [
{
id: 1,
name: 'TIFF',
description: 'Toronto International Film Festival',
date: '2015-09-10'
},
{
id: 2,
name: 'The Martian Premiere',
description: 'The Martian comes to theatres.',
date: '2015-10-02'
},
{
id: 3,
name: 'SXSW',
description: 'Music, film and interactive festival in Austin, TX.',
date: '2016-03-11'
}
];
this.$set('events', events);
},
addEvent: function() {
if(this.event.name) {
this.events.push(this.event);
this.event = { name: '', description: '', date: '' };
}
},
deleteEvent($index)"
deleteEvent: function(index){
if(confirm('Вы точно хотите удалить данную запись?')) {
this.events.$%remove(index);
}
},
cloneItem: function(index) {
}
}
});
there full code
http://codepen.io/Monocle/pen/ojLYGx
I found undocumented built it extend function Vue.util.extend that is equivalent to jQuery's extend.
In this case, you can avoid the enumerating the object properties
cloneItem: function(index) {
this.events.push(Vue.util.extend({},this.events[index]));
}
Access the cloned object via this.events[index], and then use it's properties to create new object and push it into events array:
cloneItem: function(index) {
this.events.push({ name: this.events[index].name,
description: this.events[index].description,
date: this.events[index].date });
}
Demo: http://codepen.io/anon/pen/MajKZO

ExtJs 5 Show data in grid from two stores

Is it possible to show data in table from two stores (merge them) without creating third store?
Example:
var store1 = {
data: [{
name: 'Joe'
}, {
name: 'Jane'
}, {
name: 'Kate'
}]
};
var store2 = {
data: [{
name: 'John'
}, {
name: 'Richard Roe'
}]
};
var grid = {
store: [store1, store2]
}
If both stores' models are same, why don't you merge stores' data ? then load merged data into store1. Like that: https://fiddle.sencha.com/#fiddle/tjh
var mergedData = Ext.Array.union(store1.getRange(),(store2.getRange());
store1.loadData(mergedData);
grid.setStore(store1);
// to provide unique
store1.on('datachanged', function(store) {
var checkArray = [];
Ext.each(store.getRange(), function(record) {
var userName = record.get('name');
if (checkArray.indexOf(userName) > -1) {
store.remove(record);
}
checkArray.push(userName);
});
});

Find and update items with multiple child elements

I have data as follows in MongoDB,
ITEM DATA
{
id:1,
items: {3:'three', 4:'four'}
},
{
id:2,
items: {}
},
{
id:3,
items: {1:'one', 2:'two', 6:'six'}
},
{
id:4,
items: {1:'one', 2:'two', 'three'}
},
{
id:5,
items: {1:'one', 2:'two'}
},
{
id:6,
items: {1:'one'}
}
Also I have a map of items as follows locally,
ITEM MAP DATA
{
1:'one',
2:'two',
3:'three',
4:'four'
}
Lets say i need to insert {5: 'five'}, I need to insert 5 where there are two or many items from ITEM MAP DATA. the result should reflect something similar as follows,
ITEM DATA RESULT
{
id:1,
items: {3:'three', 4:'four', 5'five'}
},
{
id:2,
items: {}
},
{
id:3,
items: {1:'one', 2:'two', 6:'six'}
},
{
id:4,
items: {1:'one', 2:'two', 'three', 5:'five'}
},
{
id:5,
items: {1:'one', 2:'two', 5:'five'}
},
{
id:6,
items: {1:'one'}
}
I am very new to this field and following was my attempt to achieve this,
var dataItemMap = {};
dataItemMap['1']='one';
dataItemMap['2']='two';
dataItemMap['3']='three';
dataItemMap['4']='four';
var setObj = {};
DbConnector.getMutProConnection(function(err,db) {
setObj['5'] = 'five';
db.collection('itemData').update({
"$where": "return Object.keys(this.items).length > 1"
}, {$set: setObj}, {multi: true});
});
I came up with the above code by reading through this post: Mongodb Query based on number of fields in a record . But didn't seem to work and I dont know how to incorporate my second query.
I would be really grateful if you experts could provide me with code snippets, examples or references where I could achieve my requirement.
Thanks alot :)
Since there are no joins in MongoDB, you would have to design your schema to avoid the lookup to "Item Map" or else you would have to check that in memory in your program. Without that condition, the query could be as below.
db.item_data.update({ "$where": "return Object.keys(this.items).length > 1" }, {$set : {"items.5" : "five"}}, false, true)

Backbone.js Error when binding a model to a view

I´m new to Backbone.js, but after some research I still couldn´t find the source of my problem.
I am developing an App and I have a collection of models, which I eventually want to display in a view (just one model at a time).
Here´s my code so far:
var App = {
Item: Backbone.Model.extend({
defaults: function() {
return {
id: -1,
name: '',
imageReference: '',
itemTags: []
};
},
sync: function() { return null; },
fetch: function() { return null; },
save: function() { return null; }
}),
Items: Backbone.Collection.extend({
model: this.Item,
}),
ItemView: Backbone.View.extend({
el: "#itemdiv",
tagName: "<div>",
className: "item",
template: _.template($("#template-item-view").html()),
initialize: function(model) {
this.model = model;
this.listenTo(this.model, "change", this.render);
this.render();
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
})
};
var items = new App.Items();
items.add(new App.Item({name: "iPhone", id: 1, imageReference: "iPhone.jpg", ["mobile", "smartphone"]}));
items.add(new App.Item({name: "MacBook", id: 2, imageReference: "MacBook.jpg", ["laptop", "computer"]}));
All of the above works. When I inspect items it has the two models including the parameters. But when I try to add a new item directly to the Collection with Collection.create() like:
items.create({name: "Apple Watch", id: 3, imageReference: "AppleWatch.jpg", ["watch", "redundant"]});
it throws an error:
TypeError: undefined is not a constructor (evaluating 'new this.model(attrs, options)')
In case it helps, this error appears in Backbone.js in line 915 (dev version), the wrapping function is
/* from Backbone.js, Dev-Version, Line 911-919 */
_prepareModel: function(attrs, options) {
if (attrs instanceof Model) return attrs;
options = options ? _.clone(options) : {};
options.collection = this;
var model = new this.model(attrs, options);
if (!model.validationError) return model;
this.trigger('invalid', this, model.validationError, options);
return false;
}
I can´t figure out if that is just a small bug or if something with my architecture is wrong. Am very thankful for help and also on comments towards best practices, etc.
Thanks in advance!
You have an error in your add lines:
items.add(new App.Item({name: "iPhone", id: 1, imageReference: "iPhone.jpg", ["mobile", "smartphone"]}));
items.add(new App.Item({name: "MacBook", id: 2, imageReference: "MacBook.jpg", ["laptop", "computer"]}));
Should be:
items.add(new App.Item({name: "iPhone", id: 1, imageReference: "iPhone.jpg", itemTags: ["mobile", "smartphone"]}));
items.add(new App.Item({name: "MacBook", id: 2, imageReference: "MacBook.jpg", itemTags: ["laptop", "computer"]}));
The field itemTags was missing. Does that fix it?
The point at which the following is run:
Items: Backbone.Collection.extend({
model: this.Item,
}),
this isn't known.
So if you're namespacing to encapsulate your code do one of either:
var App = {}
App.item = Backbone.Model.extend({...})
App.items = Backbone.Collection.extend({...})
App.itemView = Backbone.View.extend({...})
App.items.add({})
App.items.add({})
Or:
(function() {
var item = Backbone.Model.extend({...})
var items = Backbone.Collection.extend({...})
var itemView = Backbone.View.extend({...})
var items.add({})
var items.add({})
})()

Is there any key/value pair structure in JavaScript?

I want to store information like:
Pseudo-Code
array(manager) = {"Prateek","Rudresh","Prashant"};
array(employee) = {"namit","amit","sushil"};
array(hr) = {"priya","seema","nakul"};
What kind of data structure can I use?
You can use arrays to store list of data ; and objects for key-value
In you case, you'd probably use both :
var data = {
'manager': ["Prateek","Rudresh","Prashant"],
'employee': ["namit","amit","sushil"],
'hr': ["priya","seema","nakul"]
};
Here, data is an object ; which contains three arrays.
An object:
var myobj = {
"manager": ["Prateek","Rudresh","Prashant"],
"employee": ["namit","amit","sushil"],
"hr": ["priya","seema","nakul"]
}
alert(myobj['employee'][1]); // Outputs "amit"
A normal object will do:
var a = {
key1: "value1",
key2: ["value2.1","value2.2"]
/*etc*/
}
Access with:
a.key1
a["key1"]
With ES2015/ES6 you have Map type.
Using Map your code will look like
const map = new Map([
['manager', ['Prateek', 'Rudresh', 'Prashant']],
['employee', ['namit', 'amit', 'sushil']],
['hr', ['priya', 'seema', 'nakul']]
])
console.log(...map.entries())
To get Individual value you can use Map.get('key') method
you could store them in an array of objects:
var Staff = [
{ name: 'Prateek', role: manager },
{ name: 'Rudresh', role: manager },
{ name: 'Prashant', role: manager },
{ name: 'Namit', role: employee },
{ name: 'Amit', role: employee },
{ name: 'Sushil', role: employee },
{ name: 'Priya', role: hr },
{ name: 'Seema', role: hr },
{ name: 'Nakul', role: hr },
];
adding an ID attribute might be useful too depending on your application. i.e
{ id: 223, name: 'Prateek', role: manager },
Or use JSON like this. A little change of your pseudo code, but it will be serchable and extendable.
var Person = [
{
"name": "Prateek",
"position": "manager"},
{
"name": "James",
"position": "employee"}
];
Yes there is:
var theArray = {};
theArray["manager"] = ["Prateek","Rudresh","Prashant"];
theArray["employee"] = ["namit","amit","sushil"];
theArray["hr"] = ["priya","seema","nakul"];
Even you can use stuff as below :-
var obj = new Object();
obj.name = 'Jatin';
obj.place = 'Delhi';

Categories

Resources