How to get the associated store in Sencha Touch? - javascript

Hi I am working with Sencha Touch app, and I have in a one store called "Customers" one model associated, I know when you create a model associated, automatically you create a new store in background, my question is: How to get this store called "templatesStore" (I see the result in the Chrome console) to filter later?
Thank you in advance.

It can be done using following syntax:
<mainStore>.getAt(0).<assosiationName>();
For example,if main store is "Customer" & name given in association as 'Template' then:
Association given in Customer model:
hasMany: [
{
model: 'sample.model.Template',
associationKey: 'templates',
name: 'templates' // name given here will be accessed from main store
},
]
For getting the template store:
Ext.getStore('Customer').getAt(0).templatesStore;
or
Ext.getStore('Customer').getAt(0).templates();
For filtering 'Customer' store based on template value:
Ext.getStore('Customer').filter([
{ filterFn: function (item) {
item.templatesStore.filter('templateValue',templateValue); // templateValue contains the value of selected template
if(item.templatesStore.getCount()>0)
return true;
else
return false;
}
}
]);

Related

How to rename field from object

I'm using Angular 5.
I have "fake back-end" (array of items).
My case:
I'm waiting for the following structure of object:
id: number,
title: string
But, Back-End sends me wrong structure:
id: number,
name: string.
I need to receive data from back-end, and if field name (in my case "name" is wrong, should be "title") is wrong, I should RENAME field and return valid object.
P.S. I have interface and class
Good practice on large apps where you don't have much control over the backend is to create a mapper for each response type you expect.
For example you make an http request to retrieve a list of cars from your backend.
When you retrieve the response, you pass the data to a specific mapping function.
class CarMapper {
// map API to APP
public serverModelToClientModel(apiModel: CarApiModel): CarAppModel {
const appModel = new CarAppModel(); // your Car constructor
// map each property
appModel.id = apiModel.id_server;
appModel.name = apiModel.title;
return appModel; // and return YOUR model
}
}
This way on the client side you always have the correct data model. And you adapt on any model change made on the backend.
You can check if an object has name key and then create another object with title
if (obj.hasOwnProperty("name")){
var newObj = {
id: obj.id,
title: obj.name
};
}
obj = newObj;

Handling dynamic json from client in nodejs

I am developing a node js project in which the end-user can create and update outlets in mongoDb database. Now, let's say there are hundreds of fields in the outlet schema but the user may not update each and every field, i.e one may update 2 fields, other may update 3 fields. So, I want to create a function that can handle each type of request. I don't know this can be done or there is some other way, but i am new to this, can you suggest me something suitable for my project. Thanks in advance!
Sorry for the confusion earlier.
I am developing a project in nodejs for retail outlets. Each outlet has over 50 fields in the database while registering. Registration is fine. The POST request via API specifies all the data required.
But when I am planning to update any of those field. I am not sure what approach to handle. Sometimes only 1 field will be changed or next time a bunch of them with no order/sequence.
Example :
{"id":"ABCD", "name":"MNOPQR"}
{"id":"ABCD", "time":123, "name":"ZYX"}
So here in first query I need to only update the name while in next I need to update both name and time.
Is there any way I can manage the dynamic json parsing at server end and updating only those fields (int database) that are mentioned in the request.
You have several approaches you can use.
One is to accept an object with the changes:
function doTheChanges(changes) {
Object.keys(changes).forEach(name => {
const value = changes[name];
// Use `name` (the field name) and `value` (the value) to do the update
});
}
Called like this:
doTheChanges({foo: "bar", biz: "baz"});
...to change the foo field to "bar" and the biz field to "baz". (Names that have invalid identifier chars, etc., can be put in double quotse: {"I'm an interesting field name": "bar"}.)
Alternately you could accept an array of changes with name and value prperties:
function doTheChanges(changes) {
changes.forEach(({name, value}) => {
// Use `name` (the field name) and `value` (the value) to do the update
});
}
Called like this:
doTheChanges([
{
name: "foo",
value: "bar"
},
{
name: "biz",
value: "baz"
}
]);
You could also just accept a varying number of parameters, where each parameter is an object with name and value properties:
function doTheChanges(...changes) {
changes.forEach(({name, value}) => {
// Use `name` (the field name) and `value` (the value) to do the update
});
}
Called like this:
doTheChanges(
{
name: "foo",
value: "bar"
},
{
name: "biz",
value: "baz"
}
);
Note that that's very similar to the array option.
Or use the builder pattern, but it's probably overkill here.
Instead of put request you can use patch request so that only the values you change get affected in database .

interpreting backbone collection data that it received from an api controller

I'm trying to use a simple collection and view to write out data from my backbone collection to my website. I just want to iterate over the collection and display properties like Id, Name, etc. in my template.
My collection gets its data from an api controller(a sample of the data is shown below).
My limited knowledge leads me to guess that the api controller is returning an object and not JSON.
So I'm guessing that is messing up my results. I've written out the collection to my Chrome console and attached a screenshot of what I see below.
So looking at the code below, is there a way that I can format the data returned from the api so that my collection can use it effectively?
Here is the code:
var ResearchCollection = Backbone.Collection.extend({
url: '/api/lab',
getresearch: function() {
this.fetch({
url: this.url
});
}
});
var researchCollection = new ResearchCollection();
return Backbone.View.extend({
className: 'labRender',
template: _.template(tmpl, null, { variable: 'x' }),
render: function () {
researchCollection.getresearch();
console.log('collection: ', researchCollection);
}
Basically, I just want to iterate over my collection and display properties like Id, Name, etc. in my template.
Here is the raw data from the api controller that I am using to populate my collection:
{
"odata.metadata":"http://sol.edu/SOM/Api/v1/$metadata#ApiKeys","value":[
{
"odata.id":"http://sol.edu/SOM/Api/v1/ApiKeys('2f2627ed-3a97-43aa-ac77-92f227888835')","Id":"2f2627ed-3a97-43aa-ac77-92f227888835","Name":"VideoSearch","TimeoutInMinutes":20160,"IsDefault":false,"CreateAuthTicketsForResources":false,"ReportAuthFailureAsError":false,"ExcludePrivatePresentations":true,"Internal":true,"ViewOnlyAccessContext":true
}
]
}
when piped to the browser's console(why is each character a separate attribute?):
I think maybe this is because you mixed up collection and model. In Backbone, Model are fundamental unit, a Model can be used to render a template.However, Collection are ordered sets of 'Models'. So, if you just want to transform a data like you describe above, you may better select a Model instead of 'Collection'. Just try this:
var ResearchModel = Backbone.Model.extend({
initialize: function(attributes) {
this.url = 'api/lab'
}
});
// when you initialize a Model or collection, the first parameter is the attribute you want to initialize
var researchModel = new ResearchModel({});
return Backbone.View.extend({
className: 'labRender',
template: _.template(tmpl, null, { variable: 'x' }),
render: function () {
researchModel.fetch();
console.log('collection: ', researchModel);
}
Otherwise, if you just want to use collection, you had better specify its Model.Backbone use JSON, so you can also specify the model with your key.

How to not remove duplicates in collection in backbone

I create backbone collection from server JSON. Data is from mongo so each item has same objects and backbone remove this duplicates. It's unwanted behavior for me so, I can't find solution to keep this instances. After fetch my items has only 'section1' in secound object (id:2). I need the same section also in first object. For example my server response is:
items: [{
id:1,
sections: [{
id: 1.//this object is removed
name: 'section1'
}]
}, {
id: 2,
sections: [{
id:1.
name: 'section1'
}]
}]
My section model is just:
Section = Backbone.RelationalModel.extend({
});
and Item model:
Item = Backbone.RelationalModel.extend({
relations: [
{
'type': 'HasMany',
'key': 'sections',
'relatedModel': 'Section',
'includeInJSON': 'id',
'reverseRelation': {
'key': 'item',
'includeInJSON': 'id'
}
}
]
});
If I recall correctly, this plugin doesn't support many-to-many. So, what's happening is that it is attaching Section 1 to the first Item, then attaching it to the second and removing it from the first.
In fact, from the docs:
Backbone.HasMany
Defines a HasMany relation. When defining a reverseRelation, the type
will be HasOne.
Your options:
Create a SectionItem model that HasOne Section and HasOne Item. Someone posted a fiddle with this sort of setup http://jsfiddle.net/mmacaula/XaESG/2/
Use another library - or an extension of the one you use, like https://github.com/jj-studio/Backbone-JJRelational
Add a property to the Section model key that would make each one unique. This is not a good way to achieve what you are trying to do, though.
Here is a pretty good reference answer: Implementing a Many-to-Many relationship with Backbone-Relational

Update list dom only if list displayed

Sometimes we use one store for few views(list, carousel,dataviews) and when we refresh(load, filter) store data, dom of all view that use this store will be rebuild, but some views is not displayed in this time, and may be will not show with these data. How we can refresh list dom only if it displayed, not every time when it store refresh?
Issue examle
Ext.define("Test.view.Main", {
extend: 'Ext.tab.Panel',
config: {
tabBarPosition: 'bottom',
items: [ ]
},
constructor : function(){
this.callParent(arguments);
var store = Ext.create('Ext.data.Store',{
data :[
{title : 'One'},
{title : 'Two'},
{title : 'Three'}
]
}),
firstList = Ext.create('Ext.List',{
title : 'tab1',
store : store,
itemTpl : '{title}',
onItemDisclosure : function(){
store.add({title : 'Four'});
}
}),
secondList = Ext.create('Ext.List',{
title : 'tab2' ,
store : store,
itemTpl : '{title}'
}),
thirdList = Ext.create('Ext.List',{
title : 'tab3',
store : store,
itemTpl : '{title}'
});
this.add([
firstList,
secondList,
thirdList
]) ;
}
});
When tap on item in the first list, in store will be added new item. And dom of all list will be change although second and third list not displayed
I see one option. Create one main store and create separate stores for each views. And when view show fill it store from Main store. But it look not good. Any other ideas?
As far as I know, there is no "out-of-the-box" solution. The docs say that the refresh event is preventable, but I haven't tested that theory.
One other idea would be to look at the dataview source and override parts of it.
The starting point would probably be to look at the store event hooks that you can find there:
storeEventHooks: {
beforeload: 'onBeforeLoad',
load: 'onLoad',
refresh: 'refresh',
addrecords: 'onStoreAdd',
removerecords: 'onStoreRemove',
updaterecord: 'onStoreUpdate'
}
However it would probably be tedious work perfecting it.
On the other hand, your DOM shouldn't be refreshed for the other lists when adding a new record, it should only add a new list item to each list so disabling the addrecords event and then doing a complete refresh of the other lists when they are displayed will probably be more ineffective?

Categories