I'm using ExtJS framework and a run one method multiple times with different parameters.
I'm looking a way to make it more consist, easy and maintainable and I guess just vanilla Javascript solutions could handle this?
I've tried to collect each param into array and using Array.map() as well forEach() methods but I couldn't handle it.
Thanks for advance.
//ExtJS class:
Ext.define('MyApp.FooClass', {
extend: 'Ext.panel.Panel',
items: [
MyApp.createFooCard('Func1Param1', 'Func1Param2', 'Func1Param3'),
MyApp.createFooCard('Func2Param1', 'Func2Param2', 'Func2Param3'),
MyApp.createFooCard('Func3Param1', 'Func3Param2', 'Func3Param3'),
]
});
As you'll notice I totaly use same method but different arguments for each of them.
//And here is related factory-function:
createFooCard: (bindValue, userCls, glyph, label) => {
return {
itemId: bindValue,
userCls: userCls,
glyph: MyApp.getGlyph(glyph),
items: {
xtype: 'infocardfld',
fieldLabel: label,
bind: '{' + bindValue + ' || "0"}'
}
}
}
It works with Array.prototype.map to collect nested arrays and relaying those arrays with Spread syntax to run on factory-function. It should be:
Ext.define('MyApp.FooClass', {
extend: 'Ext.panel.Panel',
items: [
['Func1Param1', 'Func1Param2', 'Func1Param3'],
['Func2Param1', 'Func2Param2', 'Func2Param3'],
['Func3Param1', 'Func3Param2', 'Func3Param3']
].map(args => MyApp.createFooCard(...args));
});
If this Items array is in the global scope you could easily add elements to it inside the createFooCard function. As a example:
// Your element collection array
var items = []
//Your function
function createFooCard(bindValue, userCls, glyph, label) {
var temp = {
itemId: bindValue,
userCls: userCls,
glyph: MyApp.getGlyph(glyph),
items: {
xtype: 'infocardfld',
fieldLabel: label,
bind: '{' + bindValue + ' || "0"}'
}
};
items.push(temp);
}
You could easily pass the array as a param as well. if you wants to make it more generalized.
Related
I am currently working on an old website who works only with xslt/xml files.
I try to generate some xml from a "simple" Javascript code.
I am working with an json2xml node module who allow me to parse a Json => xml.
In some cases, i need to "return" in a loop some objects.
[
{name: 'tagName', attrs: { style: 'display:none;'}, text: 'tagContent'},
{name: 'tagOtherName', attrs: { style: 'display:none;'}, text: 'tagSomeOtherContent'},
.....
//here i want to insert others similar objects with a for loop on another array of Objects with variable content/size
function() {
....some magic function who can help me
}
]
Any idea of how i can do this iteratively?
Maybe some recursive stuff? Or transform my Object to a string then putting it in my object with a JSON.parse?
Thanks for your help!
... destructuring syntax on the outcome of a function will unpack an array of objects into your list the way you want.
[
{name: 'tagName', attrs: { style: 'display:none;'}, text: 'tagContent'},
{name: 'tagOtherName', attrs: { style: 'display:none;'}, text: 'tagSomeOtherContent'},
...(() => {
// your function to generate your objects
return [
{},
{},
{}
];
})()
]
How can I split string and get length if she bind?
I tried this, but displayed value is empty:
{
xtype: 'displayfield',
fieldLabel: __('sending_to'),
bind: {
value: '{recipients.split("\n").length}'
}
}
You can use formulas to put more logic in it. And about your question, here's the FIDDLE
We are using Backgrid which allows you to define grid columns with an array of Javascript objects which it converts to a collection. We are trying to take advantage of this to have configurable validation on a column by column basis, so we might have the following where we've added a "validator" function to a couple of the columns:
[
{
label: "Delete",
name: "delete",
cell: "boolean"
},
{
label: "Alias",
name: "alias",
cell: "string",
sortType: "toggle",
validator: function (value) {
return true;
}
},
{
label: "Assigned Server",
name: "assignedServer",
cell: "string",
sortType: "toggle",
validator: function (value) {
return new Error("Cannot Assign Server")
}
}
]
We are listening to edits to the grid in the following prescribed manner and for the purposes of this question we can ignore the model argument to the function but concentrate on the column (delete, alias or assignedServer from above) which is itself a model in a collection. So far I have a snippet of code leveraging underscore.js's _.filter that returns the validatableColumns but I want to take this further and end up with an object of the format {name: validator, etc...}. Bearing in mind my specific use case, what is a succinct way to create an object from a Backbone collection that maps model values to one another?
certificateGrid.listenTo(certificateCollection, "backgrid:edited", function (model, column) {
var validatableColumns = _.filter(column.collection.models, function (c) {
return c.get('validator');
});
//etc.
Using _.reduce seems to do the trick:
var validatorFns = _.reduce(column.collection.models, function (fns, model) {
var validator = model.get('validator');
if (model.get('validator')) {
fns[model.get('name')] = validator;
}
return fns;
}, {});
I have two grids in my application.
var columns1 = [
{
name: "Address",
field: "address"
id: "address",
sortable: true
}
]
var columns2 = [
{
{
name: "Rating, in %",
field: "rating"
id: "rating_percent",
resizable: false
}
]
They are absolutely independent from each other. Also, I have some grid events descriptions in another js file.
grid.onColumnsReordered.subscribe(function (e, args) {
_this.updateHeaderRow();
// here
});
When user changes the columns order, then I want to save this order. Should I change (overwrite) the DOM elements, I mean column1 and column2?
So question: how can I save the columns order?
njr101's answer (using store.js) is great, but note: store.js cannot store functions (i.e. for editors, formatters), so once you store.get() the columns, you'll need to add the functions back, using your original stock "columns" array:
if (store.get('gridColumns')) {
grid.setColumns(store.get('gridColumns')); // Restore settings if available
grid.getColumns().forEach(function(ch) { // Re-create editor and formatter functions
var result = $.grep(columns, function(e){ return e.id == ch.id; });
if (result[0]) {
ch.editor = result[0].editor;
ch.formatter = result[0].formatter;
}
});
}
I have done this before and the easiest way I found was to store the columns in local storage. I use the store.js library which makes this pretty simple.
grid.onColumnsReordered.subscribe(function (e, args) {
store.set('gridColumns', grid.getColumns());
});
When you want to restore the columns (e.g. when the user returns to the page) you can just call:
grid.setColumns(store.get('gridColumns'));
Can any tell me why i keep getting a method buildItems not defined in the following code ? Am i escaping something essential ?
Ext.define('MyApp.view.Viewport', {
extend: 'Ext.container.Viewport',
requires: [
'Ext.layout.container.Border'
],
layout : 'border',
items : [this.buildItems()],
buildItems : function() {
return { region:'center',xtype:'panel'}
}
});
The buildItems method has no reason to be a public method, i was only trying this way first. This is the way i'm doing it now:
(function() {
function buildItems () {
return [
{
region : 'center',
xtype : 'panel',
}, {
region : 'west',
xtype : 'panel',
width : 225
},{
region : 'south',
xtype : 'panel',
height : 50
},{
region : 'north',
xtype : 'panel',
height : 50
}
]
}
return Ext.define('MyApp.view.Viewport', {
extend: 'Ext.container.Viewport',
requires: [
'Ext.layout.container.Border'
],
layout : 'border',
items : buildItems()
});
})();
Is this an overstretch ?
thx
The problem is: At the time of execution of the line
items : [this.buildItems()],
the scope is the Global Object, i.e. this evaluates to window.
You should not put items into a class anyway, since the instances may modify the item's items, so the right way to do it is
initComponent: function () {
this.items = this.buildItems(); // now, "this" is the current component instance
// superclass.initComponent...
}
Edit: As an answer to the second part of the question
This has been discussed a million times, and there's nothing wrong with making that helper function private. I personally tend to keep methods public, since that increases readability of the code. Usually I use doc comments (#private) as a marker, and quite simply avoid calling supposedly private methods. I think this is not a big deal, since I'm mostly not building libraries or anything reusable for third-party developers.
It is because the function is defined in another function and the viewport will be accessed outside this self-executing function. So, put this buildItems() outside the self-executing function and try the same.