Please I have a challenge moving forward with this project (no server end). Consider this example:
var date = Date.now();
var item1 = new Item({date: date, title: 'breakfast', value: 100, history: false});
var item2 = new Item({date: date, title: 'lunch', value: 200, history: false});
var item3 = new Item({date: date, title: 'dinner', value: 300, history: false});
var items = new Backbone.Collection;
items.add(item1, item2, item3);
//Create a new model derived from these models and save in collection
var sum = 0;
items.each(function(elem) {
sum += parseInt(elem.get('value'));
//elem.destroy();
}
var report = new Item({date: date, title: 'Report', value: sum, history: true});
items.add(report);
Works fine. 4 models will be displayed. But I don't want to keep these 3 models in the collection once report has been computed. The 3 models should be destroyed. When I refresh the page, only report model should display. How can I achieve this?
Instead of adding the report model, use the reset function: items.reset(report)
Related
I have an array of events of type.
struct Event { var id: UUID, var title: String, var date: Date }
this array is inside another object with an occurrence title
struct Category { var occurs: String, var events: [Event] }
occurs defines if the event.date is before or after Now(), so that i can make Section Headers in a table to show Past and Upcoming sections.
I am only persisting Event(need id for Notification changes).
I am able to save and load data into an array of Category but how do I add a new event and get it into the correct "occurs" array.
Data Example (Event struc has init that assigns the UUID to id. )
[
Category(occurs: "passed", events: [
Event(title: "Yesterday", date: Calendar.current.date(byAdding: .day, value: -1, to: Date())!)
]),
Category(occurs: "upcoming", events: [
Event(title: "Tomorrow", date: Calendar.current.date(byAdding: .day, value: 1, to: Date())!),
Event(title: "Future", date: Calendar.current.date(byAdding: .day, value: 5, to: Date())!)
])
]
Category array is then consumed by a List/ForEach to spit out the Section and Body.
Thanks
First you need a way to figure out if the event has passed or is upcoming. You could add an extension to your Event struct to compute this:
extension Event {
var occurs: String {
let diff = date.timeIntervalSince1970 - Date().timeIntervalSince1970
return diff >= 0 ? "upcoming" : "passed"
}
}
Next you need to find the index of the category that matches the event's occurs value in your data array. You can do this by using the firstIndex method:
let newEvent = Event(
title: "2 hours from now",
date: Calendar.current.date(byAdding: .hour, value: 2, to: Date())!)
let newEventOccurs = newEvent.occurs
if let index = data.firstIndex(where: { $0.occurs == newEventOccurs }) {
data[index].events.append(newEvent)
}
Notice we use an if-let binding because it's possible you don't have a category in your array for the event. In this case, you will want to add the category to your array with the new event.
The upcomingWork contains my apis data. What I want here is to insert this as an array to display it on my calendar, below are the example of structured data I want.
Actually, the upcomingWork contains a lot of attributes but I just want to get those three attributes to display on my calendar.
const data = upcomingWork.map(u => u.id && u.title && u.created_at);
Example of array that I want to create from data.
const events = [
{
id: 1,
title: 'My event',
start: new Date(2020, 4, 8, 10, 0),
end: new Date(2020, 4, 8, 14, 0),
},
];
The map that you have will simply set every value to either true if all values are truey or false if any of them are falsey. if you want to extract those 3 values just change the map to this:
const data = upcomingWork.map(({id, title, created_at}) => ({id, title, created_at}))
Whatever you returned is not going to give you any desired data.
I think you misunderstood the map method of Array.
Instead you should use map like:
const data = upcomingWork.map(u => {
const {id, title, created_at} = u;
return {
id,
title,
created_at
}
});
const data = upcomingWork.map(u => {
return { id: u.id, title: u.title };
});
Your upcomingWork.map doesn't create an object at all, so it has no chance of creating the expected data. Instead, you can map appropriate properties of the u object to the new keys in a new object you create.
const events = upcomingWork.map(u => ({
id: u.id,
title: u.title,
start: u.created_at,
end: u.end //change the u.end to whatever property you have in your data
}));
(the new object has to be wrapped in () to ensure JS interprets it as a value, not a function body)
I am trying to add a couple of models to the collection
rolesSuccess: function(roles) {
var role1 = new Role({
id: "1",
Name:"TST1",
Description:"Test 1"
});
var role2 = new Role({
id: "2",
Name:"TST2",
Description:"Test 2"
});
roles = new Roles();
roles.add(role1);
roles.add(role2);
this._context.roles(roles);
}
I only see one role being added at any point, just the first one. What am I doing wrong?
you can pass an array of models to a backbone collection when you initialize it.
var roles = new Roles([role1, role2]);
Let's suppose I have the following model (model1) and collection (collection1)
model1.attributes = {
name: 'bar'
};
collection1.models = [{}, {}, {}];
It will be possible by using backbone relation to make the model1 to know about the length of collection1?
model1.attributes = {
name: 'bar',
collection1Length = 3 // collection1.models.length
}
Thanks
Based on your comments, it might be best to simply create a reference to the collection itself within the model:
ModelName = Backbone.Model.extend({
...
linked_collection: null // don't call this 'collection', as model.collection already exists
...
}
var model1 = new ModelName();
model1.set('linked_collection',collection1);
Now you can do this at any time to get the linked collection's length.
model1.get('linked_collection').length
I have 2 models - for example - Users and Orders
Ext.define('AM.model.User', {
extend: 'Ext.data.Model',
fields: ['id', 'username', 'firstName', 'lastName', 'state', 'city'],
associations: [
{
type: 'hasMany',
model: 'Order',
name: 'orders'
},],
});
Ext.define('AM.model.Order', {
extend: 'Ext.data.Model',
fields: ['id', 'userId', 'date', 'description', 'value'],
belongsTo: 'User',
});
and their stores. I'm looking for a way to display data from both stores in grid. (so my columns would be firstName, lastName, orderDate, orderDescription, orderValue...
What is the proper way to display them?
Thanks.
You should do this with your server side code and get this all data into a single store.
If you want to do this with associations, you need to define a renderer for your grid column.
Like so:
{
text: "orderDescription",
renderer: function(value,meta,record){//1.
//var orderStore = record.orderStore;//2a.
//var orderList = ordersStore.data.items;//2b.
var orderList = record.orders().data.items; //3.This line is the same as 2 the lines above(2a,2b).
var order = orderList[0]; //4. TODO..loop through your list.
var description = order.data.description; //5.
return description ;
},
I will try to explain for anyone who wants to do it this way.
The third parameter is the current record in your 'User' Store being renderd for the grid. The first two just need to be there, to receive record. Leaving them out will not work.
1a/1b. I left these there to demonstrate how the association works. Basically, each record in your 'User' Store gets its own corresponding 'ordersStore'. It will be called 'ordersStore', because you put in your association [name: 'orders'].
The orders() method is automatically created, again based on the name 'orders'. This just returns the orderStore. The store contains a field data -> which contains a field items. items is the actual list of orders.
Now you have access to your list of orders. You can loop trough the orders now. Or if you have only one order, just the first one.
Your order again contains a field data which contains your actual data.
Lets try with below example-
Step 1: Adding records from Store 2 to Store 2.
var store2 = new Ext.data.Store({
...
});
var store1 = new Ext.data.Store({
...
listeners: {
load: function(store) {
store2.addRecords({records: store.getRange()},{add: true});
}
}
});
Step 2: Using records from Store 2 with Store 1.
For example, the first data col comes from Store 1 and the data from Store 2 forms cols 2 and 3. You can use a renderer that finds the data in the second store if the 'other' columns are just 'lookup' data, e.g.:
var store1 = new Ext.data.Store({
...,
fields: ['field1', 'field2']
});
var store2 = new Ext.data.Store({
...
id: 'field2',
fields: ['field2', 'fieldA', 'fieldB']
});
var renderA = function(value) {
var rec = store2.getById(value);
return rec ? rec.get('fieldA') : '';
}
var renderB = function(value) {
var rec = store2.getById(value);
return rec ? rec.get('fieldB') : '';
}
var columns = [
{header: 'Field 1', dataIndex: 'field1'},
{header: 'Field A', dataIndex: 'field2', renderer: renderA},
{header: 'Field B', dataIndex: 'field2', renderer: renderB}
];
Best of luck.
Ref. from here