Backbone: Order of models inside a collection - javascript

We created a Collection of models from an array as given below. Our question is: will the Collection preserve the same order of elements/models as it was present in the original array? In other words, is the same order (of source array) guaranteed in Collection?
var colorsData = [
{
name: 'red'
},
{
name: 'blue'
},
{
name: 'green'
},
.....
.....
.....
//other colors
];
var Color = Backbone.Model.extend({
defaults: {
name: 'white'
}
});
var ColorCollection = Backbone.Collection.extend({
model: Color
});
var colorCollection1 = new ColorCollection(colorsData); //creating a collection from the source array colorsData.

From all that I can gather, yes a Collection preserves the original order of elements.
You can read the annotated source for collection to see for yourself that it isn't magically shuffled time to time. Such functions as at, unshift, pop, push, etc. are quite clear indications of this.
You can read the annotated source for parse, which is used to parse the response from server after for example fetch -oprations:
parse: function(resp, xhr) {
return resp;
},
To ascertain that whatever is passed on to your collection won't be shuffled anywhere. The resp will be passed on to the add -function that will process the response in natural order.

As stated in http://backbonejs.org/#Collection
collection.at(index) retrieves models in insertion order.

Related

How to update the value of a single property within a state object in React.js?

So I have the following object structure:
const SamplePalette = {
id: 1,
name: "Sample Palette",
description: "this is a short description",
swatches: [
{
val: "#FF6245",
tints: ["#FFE0DB", "#FFA797"],
shades: ["#751408", "#C33F27"]
},
{
val: "#FFFDA4",
tints: ["#FFFFE1"],
shades: ["#CCCB83"]
},
{
val: "#BFE8A3",
tints: ["#E7FFD7"],
shades: ["#95B77E"]
}
]
}
Let's imagine that this object is managed by the state of my app like this:
this.state = {
currentPalette: SamplePalette,
}
My question is how would I go about updating the val property of a given swatch object in the swatches array? Or more generally - how do I only update pieces of this object?
I tried using the update helper as well as to figure out how Object.assign() works, however I've been unsuccessful and frankly can't really grasp the syntax by just looking at examples.
Also, since I'm going to be modifying this object quite a lot, should I look into maybe using Redux?
[EDIT]
I tried #maxim.sh suggestion but with no success:
this.setState(
{ currentPalette: {...this.state.currentPalette,
swatches[0].val: newValue}
})
Consider you have new new_swatches
I think the clearer way is to get array, update it and put back as:
let new_swatches = this.state.currentPalette.swatches;
new_swatches[0].val = newValue;
this.setState(
{ currentPalette:
{ ...this.state.currentPalette, swatches: new_swatches }
});
Also you have : Immutability Helpers or https://github.com/kolodny/immutability-helper
Available Commands
{$push: array} push() all the items in array on the target.
{$unshift: array} unshift() all the items in array on the target.
{$splice: array of arrays} for each item in arrays call splice() on the target with the parameters provided by the item.
{$set: any} replace the target entirely.
{$merge: object} merge the keys of object with the target.
{$apply: function} passes in the current value to the function and updates it with the new returned value.

ReactJS setting unique keys for resortable list elements

I'm creating a list GUI which can be re-arranged by drag and drop. Data comes from an existing API as an array of objects such as:
var dataFromApi = [
{name: 'jack', label: 'Test element'},
{name: 'john', label: 'Test element 2'}
];
There are many more properties per object, but there is no unique ID field for any object. The nature of data means that duplicate objects are permitted.
I used a React class to render these as a list:
var List = React.createClass({
getDefaultProps: function() {
return {
data: []
};
},
getInitialState: function() {
return {
data: this.props.data
};
},
render: function() {
return (
<ul>
{
this.state.data.map(function(item, idx) {
return (
<li>{item.name}</li>
);
})
}
</ul>
);
}
});
I tried adding some drag-and-drop code, to allow the list to be re-ordered and the state to be updated accordingly. However, to re-order I need each <li key={something?}> element to have a unique key attribute which isn't the index.
What would be the best way add a unique key to each element, but not have this key in the data if I ever needed to send the changes up to a parent element - such as for saving the data to the server.
try doing both, <li key=idx+item> think that would solve your problem
Tried almost everything, setting the key as a combination of item properties and index, but nothing seemed to work if I wanted to allow re-arranging of child elements.
In the end I generated a random key for each object just after an API call which worked and allowed items to be re-arranged.

How to get data out of ember objects

I'm fairly new to ember and I'd like to know whats the fastest way to extract the data out of ember objects. I've loaded my model with a very large amount of records using this.store.find('modelName);` in my route.
I created a component on my view using {{kendo-ui.kendo-table descriptor=tableDescriptor data=model}}. My controller defined other arguments to be passed to my component (descriptor).
In my components.js I'm' getting the data passed over by using
export default Ember.Component.extend({
didInsertElement: function() {
var columns = this.get('descriptor.columns'); // this is right
var model = this.get('data')['content']; // this returns the objects of the model
var height = this.get('descriptor.height'); // this is ok too
Ember.$('#kendo-table').kendoGrid({
dataSource: {
data: model,
pageSize: 100
},
height: height,
scrollable: {
virtual: true
},
groupable: true,
sortable: true,
columns: columns
});
}
});
On the line var model = this.get('data')['content'];, this gives me an Array of Ember Classes. Inside each class, there is a _data object that holds the value of the actual class.
The easiest solutions is to just loop through and extract the _data but that is no good for larger model array. Is there a quick way to extract all the _data from my array of ember objects?
You could use getProperties method. http://emberjs.com/api/classes/Ember.Object.html#method_getProperties
To get the values of multiple properties at once, call getProperties with a list of strings or an array:
record.getProperties('firstName', 'lastName', 'zipCode');
// { firstName: 'John', lastName: 'Doe', zipCode: '10011' }
You could define computed property dataArray:
dataArray: function() {
return this.get('data').map( function(item) {
return item.getProperties('id', ... ); // your list of properties
});
}.property('data.[]'),
didInsertElement: function() {
//...
Ember.$('#kendo-table').kendoGrid({
dataSource: {
data: this.get('dataArray'),
//...
},
// ...
});
}
UPDATE:
for records (DS.Model) you could use toJSON method. Use DS.JSONSerializer to get the JSON representation of a record.
toJSON takes an optional hash as a parameter, currently supported options are:
includeId: true if the record's ID should be included in the JSON representation.
http://emberjs.com/api/data/classes/DS.Model.html#method_toJSON

How can I fake Collection data?

What I mean by this is I want to create it artificially.
This is for testing purposes.
But for models, it is quite simple. I just set defaults I instantiate the model object and from there I can use this.model.toJSON() to grab the created data.
I want to use this same trick with collections. Is there a similar way to do this with collections? What I would want to do is have the collection create x ( 8 in this case ) copies of Model defaults.
Basically what I was doing before for models but a little bit more complex as it applies to Collections.
Here is the actual use case. It should be simple.
/**Model
**/
// name, picture, time, tweet, h_file
var FeedRow = Backbone.Model.extend({
Name: 'FeedRow',
defaults: {
name: "default",
picture: 0,
time: "0",
tweet: "default",
h_file: "default"
}
});
/**Collection
**/
var FeedTable = Backbone.Collection.extend({
Name: 'FeedTable',
model: FeedRow
});
When your FeedTable collection is constructed you could set the model on it multiple times in the initialize method.
var FeedTable = Backbone.Collection.extend(
{
Name: 'FeedTable',
model: FeedRow,
initialize: function()
{
model = this.model;
models = [];
_.times(8, function(n)
{
models.push(new model({id: (n + 1)}));
});
this.set(models);
}
});

knockout: extending mapping to complex JSON

I receive a complex JSON from the server. Let it be next:
var data = [{
name: "name1",
items:[
{
name:"name11",
subItems:[{
name:"name111",
children[
{id:1,name:"child1111",status:"good"},
{id:2,name:"child1112",status:"bad"},
{id:3,name:"child1113",status:"good"}
]},
{
name:"name112",
children[
{id:4,name:"child1121",status:"good"}]
}]
},
{
name:"name12",
subItems:[{
name:"name121",
children[
{id:5,name:"child1211",status:"bad"}]
}]
}]
},
{
name: "name2",
items:[
{
name:"name21",
subItems:[{
name:"name111",
children[
{id:7,name:"child2111",status:"good"}
]}]
}]
}];
So I have the list of objects each one contains name and items properties. Items is property of the similar list of objects each one contains name and subItems properties. subItems property same to previous and has name and children properties. children is list of my entities. I use mapping for filling my ViewModel.
First of all I can't image how to set as key id in my entity. I am wondering how to "dive" to it. Moreover, I need to extend my entity. Add the compute property like next example:
computProp: ko.computed(function() {return name+status;})
I don't want to create js classes, because I don't see benefits of mapping on this case. I can implement manual mapping in this case. It would be more clear for me.
So any idea, suggesting or critics are welcome.
PS: I have searched/read similar topics
You must explicit declare the children viewmodel to get this behaviour, but you still benefit from getting all the mapping done
http://jsfiddle.net/uXMhA/
ChildViewModel = function(data) {
ko.mapping.fromJS(data, {}, this);
this.computProp = ko.computed(function() {
return this.name() + this.status();
}, this);
};

Categories

Resources