Sencha Touch add function to Sencha Component - javascript

I want to add a function to the Store Class for cleaning the store(proxy+data+sync), which I can call it via myStoreVariable.cleanAll(); or Ext.getStore('storeId').cleanAll();
My first attempt is this, but I can't call this function from the store:
Ext.data.Store.cleanAll = function() {
this.getProxy().clear();
this.data.clear();
this.sync();
};
My second attempt is this:
this.storeStore = Ext.create('Ext.data.Store', { id: 'myStore', model: 'myModel' });
this.storeStore.cleanAll = function() { /* my cleaning code(see above) */ };
It is working, but I don't want to define cleanAll for all of my stores.
Do you know any possibility to add this function to the store class? So I can call it from any store I create via Ext.create('Ext.data.Store',

I found a way, overriding / adding a method to Ext.data.Store
Put this code into your launch config of your Ext.Application
launch: function() {
Ext.override(Ext.data.Store, {
cleanAll: function() {
this.getProxy().clear();
this.data.clear();
this.sync();
}
});
}

Related

cannot override mixin behavior after it's used in a class definition

I need to override some member functions added by a mixin from a 3rd-party library. The problem is: the mixin is used in multiple 3rd-party class definitions immediately, in the same script file where the mixin is defined. And I can only insert custom code before or after this script, but not in between. If I call override afterwards, then already defined classes don't obtain my function in the call chain.
// library script BEGIN
Ext.define('Foo.bar.Base', {
});
Ext.define('Foo.bar.Util', {
newmember: function() {
console.log('newmember');
}
});
Ext.define('Foo.bar.Derived', {
extend: 'Foo.bar.Base',
mixins: {
fooutil: 'Foo.bar.Util'
}
});
// library script END
Foo.bar.Util.override({
newmember: function () {
console.log('newmember2');
this.callParent();
}
});
var obj = new Foo.bar.Derived();
obj.newmember();
Actual Output:
newmember
Desired Output:
newmember2
newmember
Override before defining a class using a mixin. This can be done using override as a property when defining:
Ext.define('Foo.bar.UtilOverride',{
override: 'Foo.bar.Util',
newmember: function () {
console.log('newmember2');
this.callParent();
}
});
// library script BEGIN
Ext.define('Foo.bar.Base', {
});
Ext.define('Foo.bar.Util', {
newmember: function() {
console.log('newmember');
}
});
Ext.define('Foo.bar.Derived', {
extend: 'Foo.bar.Base',
mixins: {
fooutil: 'Foo.bar.Util'
}
});
// library script END
var obj = new Foo.bar.Derived();
obj.newmember();

Emberjs: Handling form submission, params, access to model

(Warning: newbie) Going around the block on this one, as each example I see does it differently (and none work for me)
var InitiativesNewRoute = Ember.Route.extend({
model: function(params) {
return this.store.createRecord('initiative', params);
},
actions: {
submit: function() {
var initiative = this.get('model');
initiative.save().then(function(model) {
this.transitionTo('initiatives.show', initiative);
});
}
}
});
Saving barfs as initiative is undefined, but I see a record created in the ember chrome plugin. So it looks like creating the record in model works, but fetching it in the action doesn't.
Also tried this example:
submit: function(initiative) {
initiative.save().then(function(model) {
this.transitionTo('initiatives.show', initiative);
});
}
Without passing passing params to createRecord above, and I get the same error. How do I do this?
Using ember-cli 0.0.39 and easy-form, with the fixture adapter.
Got some help on #emberjs and managed to get it working like this:
var InitiativesNewRoute = Ember.Route.extend({
model: function(params) {
return this.store.createRecord('initiative', params);
},
actions: {
submit: function() {
var _this = this;
var initiative = this.get('controller.model');
initiative.save().then(function(model) {
_this.transitionTo('initiatives.show', model.get('id'));
});
}
}
});

extjs store update not firing

I'm using Extjs 4.1 MVC, I have a simple store :
Ext.define('Proj.store.GraphData', {
extend: 'Ext.data.Store',
model: 'Proj.model.GraphData',
autoLoad: false,
proxy: {
type: "ajax",
reader: {
type: 'json',
root: 'data'
}
}});
I want to handle its update event from the controller, so this is the controller :
Ext.define('Proj.controller.RenderGraph', {
extend: 'Ext.app.Controller',
stores: ['GraphData'],
models : ['GraphData'],
init: function () {
var me = this;
me.getGraphDataStore().addListener('update',this.onStoreUpdate, this);
this.control({
....
})
},
onStoreUpdate : function () {
alert('OKK');
}
But when I update the store, it doesn't show anything, what am I doing wrong please?
The first thing would be to use the full path name of your store when you are defining it in the controller
...
stores: ['Proj.store.GraphData'],
...
Also, I think listener you are looking for would be load. According to the docs, update fires when the model instance has been updated. load fires whenever the store reads data from a remote data source.
http://docs.sencha.com/extjs/4.2.0/#!/api/Ext.data.Store-event-load
me.getGraphDataStore().addListener('load',this.onStoreUpdate, this);

EmberJS: initialize nested model with parent model loaded by ajax

I got the following simple ember.js-setup, which works all great
App.Router.map(function() {
this.resource('tourdates', function() {
this.resource('tourdate', { path: ':tourdate_id' });
});
});
App.TourdatesRoute = Ember.Route.extend({
model: function() {
return $.getJSON('http://someapi.com/?jsoncallback=?').then(function(data) {
return data;
});
}
});
App.TourdateRoute = Ember.Route.extend({
model: function(params) {
return tourdates.findBy('id', params.tourdate_id);
}
});
so, pretty simple, whenever i call index.html#/tourdates, i get the data via api. and when I click on a link in this view and call f.e. index.html#/tourdates/1 it just displays the view for its nested child.
This all breaks, when I directly call index.html#/tourdates/1 with the message
DEPRECATION: Action handlers contained in an `events` object are deprecated in favor of putting them in an `actions` object (error on <Ember.Route:ember174>)
Error while loading route: ReferenceError {}
Uncaught ReferenceError: tourdates is not defined
Although he makes the ajax-call to the api and gets the data, he is not able to initialize the nested model
When your App.TourdatesRoute is loaded, all data from the json, will be rendered. And when you click to edit one of these loaded objects, using a link-to for example, ember is smart enough to get the already referenced object, instead of send a new request. So your url will change to: yourhost.com/tourdate/id.
When you direct call this url, it will call the App.TourdateRoute model method. Because doesn't have any pre loaded data. But in your case you have a:
tourdates.findBy('id', params.tourdate_id);
And I can't see in any place the declaration of tourdates.
I recommed you to change your TourdateRoute to TourdateIndexRoute so when transitioning to tourdates the ajax call is performed once:
App.TourdatesIndexRoute = Ember.Route.extend({
model: function() {
return $.getJSON('http://someapi.com/?jsoncallback=?').then(function(data) {
return data;
});
}
});
The TourdatesRoute is called both for TourdateRoute and TourdatesIndexRoute, because it's the parent route of both. So fetching all data in the TourdatesIndexRoute will ensure this is just called when transitioning to tourdates.
In your TourdateRoute you will load just the record needed. Something like this:
App.TourdateRoute = Ember.Route.extend({
model: function(params) {
// retrieve just one data by id, from your endpoint
return $.getJSON('http://someapi.com/' + params.tourdate_id + '?jsoncallback=?').then(function(data) {
return data;
});
}
});
So a direct call to yourhost.com/tourdate/id will just loaded one record.
About your warning message, it happens because in some route you have:
App.MyRoute = Ember.Route.extend({
events: {
eventA: function() { ...},
eventB: function() { ...},
}
});
The events is deprecated and you need to use actions:
App.MyRoute = Ember.Route.extend({
actions: {
eventA: function() { ...},
eventB: function() { ...},
}
});
I hope it helps

Pass config to a custom Ext.tree.Panel and then to a custom Ext.data.Store

How can I pass a variable to an extended Ext.tree.Panel, which in turn, will pass it a custom Ext.data.Store.
Here is my code:
Ext.define('CustomStore', {
extend: 'Ext.data.TreeStore',
alias: 'widget.customstore',
folderSort : true,
model : 'TreeNode',
autoLoad: true,
config: {
customParam: 'defaultVal'
},
...
proxy: {
url: '/some/url?param'+this.customParam,
...
}
});
Ext.define('CustomTree', {
extend: 'Ext.tree.Panel',
alias: 'widget.customtree',
config: {
customParam2: 'defaultVal'
},
store: new CustomStore({customParam: this.customParam2'}),
...
});
var tree = Ext.create('CustomTree', {customParam2: 'someVal'});
As you can see, I want to pass a value someVal to the tree, which should pass it down to the store, the proxy of the store then needs to pick it up and use in its load url.
Tried many things, to name a few: config, initConfig, constructor, initComponent but with no good outcome.
You've got the right ingredients but you don't mix them in the right order.
The problem here is that your store creation code:
new CustomStore({customParam: this.customParam2'})
gets called before the definition of CustomTree:
Ext.define('CustomTree', ...)
This is because new CustomStore(...) is used as argument to the define function. So, obviously, it is also called before the line that sets the value of customParam2:
var tree = Ext.create('CustomTree', {customParam2: 'someVal'});
So in order to make it work, you want to create your store when the constructor of CustomTree is called. But when working with components, it is best to override initComponent instead of the constructor. So here's how you should do it:
Ext.define('CustomTree', {
extend: 'Ext.tree.Panel',
alias: 'widget.customtree',
config: {
customParam2: 'defaultVal'
},
// remove that
// store: new CustomStore({customParam: this.customParam2'});
// ... and put it in there:
initComponent: function() {
// creates the store after construct
this.store = new CustomStore({customParam: this.customParam2});
// call the superclass method *after* we created the store
this.callParent(arguments);
}
...
});
As for initConfig, you have to call it in the constructor in order for you're config params to be applied. But in your case, you're extending from Ext.data.Store and Ext.tree.Panel, and their constructor already calls it, so you don't have to do it yourself.

Categories