I'm working on Ext JS MVC app, that needs to be localized. Trying to reproduce official docs (http://docs.sencha.com/extjs/6.2.0/guides/core_concepts/localization.html).
Locale file load correctly.
Console message:
[W] Overriding existing mapping: 'viewmodel.users' From
'clt.locale.en.view.users.UsersModel' to 'clt.view.users.UsersModel'.
Is this intentional?
but overriding values don't display (they should be grid columns headers.
Model looks like this:
Ext.define('clt.view.users.UsersModel', {
extend: 'Ext.app.ViewModel',
requires:[
// something
],
// singleton: true,
data: {
key1: 'value1',
key2: 'value2',
keyN: 'valueN',
},
stores: {
// something
}
});
Values binding to view like this:
bind: { text: '{key1}' }
If I make this model singleton, localization starts working (grid headers displayed localized values), but grid data is empty.
So, what's the problem? Help me understanding it.
Update. Problem resolved. I found thread on Sencha forum with solution: add localized elements in config object in localization file. Example:
Ext.define('clt.locale.en.view.users.UsersModel', {
override: 'clt.view.users.UsersModel',
config: {
data: {
key1: 'value1',
// some other keys
}
}
});
Warnings are not a good sign. In your case, you don't apply an override like you should. The message
[W] Overriding existing mapping: 'viewmodel.users' From 'clt.locale.en.view.users.UsersModel' to 'clt.view.users.UsersModel'. Is this intentional?
says that first, clt.locale.en.view.users.UsersModel (your localized version) is loaded, and after that, clt.view.users.UsersModel (non-localized version) is loaded and completely replaces the localized version.
What you want to do is the following:
Ext.define('clt.view.users.UsersModel', {
extend: 'Ext.app.ViewModel', // <- EXTEND ViewModel class
// define your locale-agnostic user model here
});
Ext.define('clt.locale.en.view.users.UsersModel', {
override: 'clt.view.users.UsersModel', // <- OVERRIDE implementation in the overridden class
// define your localized properties here.
});
This should remove the warning. Then you can instantiate the UsersModel
Ext.create('clt.view.users.UsersModel', {
but you get a localized version of it.
Related
I want to create a custom property editor, that makes use of the media picker. Right now my controller looks like this:
angular.module("umbraco").controller("My.MediaCropperController",
function($scope, dialogService) {
$scope.mediaPicker = {
view: 'mediapicker',
value: null, // or your value
config: { disableFolderSelect: true, onlyImages: true }
};
});
And my view looks like this:
<umb-editor ng-controller="My.MediaCropperController" model="mediaPicker" ng-if="mediaPicker">
</umb-editor>
As I understand it, I need to create config object for built-in editors, then use in the template to show the editor. However when i bring my property editor into my backoffice, nothing is being shown. What am I doing wrong here?
This is my package manifest file:
{
//you can define multiple editors
propertyEditors: [
{
/*this must be a unique alias*/
alias: "My.MediaCropper",
/*the name*/
name: "My Media Cropper",
/*the html file we will load for the editor*/
editor: {
view: "~/App_Plugins/MediaCropper/mediacropper.html"
}
}
]
,
//array of files we want to inject into the application on app_start
javascript: [
'~/App_Plugins/MediaCropper/mediacropper.controller.js'
]
}
dialogService.mediaPicker rather than $scope.mediapicker ?
May be what is causing your error, just from comparing my script to yours.
For testing purposes, I made 2 views. One that requires the other view. Now I want people to be able to open components multiple times as a tab, so I obviously have to assign unique ID's to each tab and element inside of the component, right?
My question is, how can I access one of the root properties in a view from say the docketItems object?
In the code below, it will cause an undefined this.varindex error at id: 'accountSearchField' + this.varindex,. varindex is dynamically assigned from the other component. (I hardcoded it in the example code below)
Note that I will not know the exact ID, so I can not use something such as Ext.getCmp. I could make use of Ext.ComponentQuery.query('searchAccount') but perhaps there is a better way to do this?
Listed below is a portion of the code that is required by my main component.
Ext.define('cp.views.search.Account', {
extend: 'Ext.panel.Panel',
xtype: 'searchAccount',
varindex: "uniqueid_assigned_by_main_component",
listeners: {
beforerender: function(){
this.id = 'panelSearchAccount' + this.varindex
}
},
items: [
{
xtype: 'grid',
store: {
type: 'Account'
},
id: 'searchAccount' + this.varindex,
columns: [
///
],
dockedItems: [
{
xtype: 'fieldset',
items: [
{
id: 'accountSearchField' + this.varindex,
xtype: 'searchfield'
}
]
}]
}
]
});
Ext will generate IDs for DOM elements and ensure they are unique to the page, so it is unusual to use the id attribute for referencing components. There are two configuration properties with this purpose, itemId and reference.
There are multiple methods that can be used to acquire a component by itemId from a parent container or globally.
Ext.container.Container.getComponent
Ext.container.Container.query
Ext.container.Container.down
Ext.container.Container.child
Ext.ComponentQuery.query
Additionally, components can be acquired by Ext.app.Controllers using the refs configuration. These methods take a selector string. The selector for an itemId is the itemId prefixed with '#' (e.g. '#itemId'). You do not specify the '#' when configuring a component with an itemId.
Introduced along with support for MVVM in Ext JS 5, the reference identifier is unique to the component's container or ViewController. A component can be acquired by reference from components or ViewControllers using lookupReference. The lookupReference method takes only references as input and therefore, does not require a prefix.
If you want to be able to reference a component associated with a particular model instance (account), you can define the component class with an alias and configure the reference or itemId when you add each instance to the container.
for (var i = 0, ilen = accountModels.length; i < ilen; ++i) {
container.add({
xtype: 'accountpanel',
reference: accountModel[i].get('accountNumber')
});
}
In this example, an account's associated panel can be acquired later on using the account number.
var accountPanel = this.lookupReference(accountModel.get('accountNumber'));
Actually I may have figured it out. I simply moved the items inside of the beforerender event and made use of the this.add() function.
I just installed a copy of MODX Revolution 2.3.1-pl.
And everything is fine, but comboboxes are empty. I can see that combobox data comes with JSON/AJAX and JSON is correct. But anyway I cannot see a proper values on the combo box.
What's wrong with that?
First create the imaevents.combo.js file here modxcloud\assets\components\yourcomponentFolder\js\mgr\widgets and add this code in imaevents.combo.js:
Imaevents.combo.Event_status = function(config) {
config = config || {};
Ext.applyIf(config,{
store: new Ext.data.ArrayStore({
id: 0
,fields: ['event_status','display']
,data: [
['','Event Status']
,['Normal','Normal']
,['Closed','Closed']
,['Cancelled','Cancelled']
,['Full','Full']
,['Waiting list','Waiting list']
]
})
,mode: 'local'
,displayField: 'display'
,valueField: 'event_status'
});
Imaevents.combo.Event_status.superclass.constructor.call(this,config);
};
Ext.extend(Imaevents.combo.Event_status,MODx.combo.ComboBox);
Ext.reg('imaevents-combo-event_status',Imaevents.combo.Event_status);
Use this combo box by calling the xtype "imaevents-combo-event_status"
{
xtype: 'imaevents-combo-event_status'
,fieldLabel: _('imaevents.event_status')
,name: 'event_status'
,anchor: '100%'
}
Well, I found the problem is in unsupported experimental ES6 features (Chrome flag #enable-javascript-harmony) by the legacy ExtJS 3.X.
See also: Comboboxes are ed up in Chrome
I am working on a switch from version 4.1.1 to 4.2.1 and finally I need to fix hopefully the last bug. We have a gridview with view being overriden by simple (?) Ext.XTemplate, as follows:
Ext.define('view.monitoring.Event',
{
extend: 'Ext.view.View',
alias: 'widget.default_monitoring_event',
itemSelector: '.monitoring-thumb-fumb',
tplWriteMode: 'overwrite',
autoWidth: true,
initComponent: function()
{
var tplPart1 = new Ext.XTemplate('<SOME HTML 1>');
var tplPart2 = new Ext.XTemplate('<SOME HTML 2>');
var tplPart3 = new Ext.XTemplate('<SOME HTML 3>');
var tplPart4 = new Ext.XTemplate('<SOME HTML 4>');
this.tpl = new Ext.Template('<BUNCH OF HTML AND TPL and TPL INSIDE TPL',
callFunc1: function(data) { /* do something with tplPart1 */ },
callFunc2: function(data) { /* do something with tplPart2 */ },
callFunc3: function(data) { /* do something with tplPart3 */ },
callFunc4: function(data) { /* do something with tplPart4 */ },
);
this.callParent(arguments;
}
}
This view is set for the grid in this way:
Ext.define('view.monitoring.WeeklyOverview',
{
extend: 'Ext.grid.Panel',
alias: 'widget.default_monitoring_weeklyoverview',
layout: 'border',
title: Lang.translate('event_monitoring_title'),
overflowX: 'hidden',
overflowY: 'auto',
initComponent: function()
{
//...
this.view = Ext.widget('default_monitoring_event', {
store: Ext.create('store.monitoring.Rows')
});
//...
}
}
Then in controller onRender the stores gets populated (the store of the grid is AJAX, loads the data and passes them to a memory store of the view). In ExtJS 4.1.1 this is working properly, data are loaded and the template is parsed and HTML is displayed containing the data.
But after the switch to 4.2.1 the HTML is no longer filled with the data and nothing is displayed but an empty HTML table (which appears as like nothing would be rendered). As there is at least some part of HTML but no data, I guess the problem might be with the data being applied for the template.
Does anybody know what might be/went wrong?
UPDATE: After debugging and the custom view template simplification I have found out, that even the custom view has set it's own store with it's own root for the data returned, it ignores that setting and simply loads the data for the store of the Ext.grid.Panel component. The AJAX response looks like:
{
user: {},
data: [
0: { ... },
1: { ... },
...
],
rows: [
0: { ... },
1: { ... },
...
]
}
Here the data should be used for Ext.grid.Panel component and the rows should be then populated by the custom view (configured with Ext.XTemplate). Seems like for the children views always the parent's store's root element is returned. Any way how to workaround this behaviour and make the custom view to use it's own store???
Finally found a solution.
The problem was that after the main grid.Panel loaded the data it distributed them also to it's (sub)view. After that even I had manually loaded the right data into this custom XTemplate, it needed to also manually override previously rendered view.
In my controller (init -> render) I needed to do this:
var me = this;
this.getMainView().store.load({
params: params || {},
callback: function(records, operation, success) {
// this line was already there, working properly for ExtJS 4.1.1, probably is now useless for ExtJS 4.2.1 with the next line
me.getCustomView().store.loadRawData(this.proxy.reader.rawData);
// I had to add this line for ExtJS 4.2.1...
me.getCustomView().tpl.overwrite(me.getCustomView().el, this.proxy.reader.rawData.rows);
}
});
This is kinda strange as I thought that with a definition within a custom view (see my question above)
tplWriteMode: 'overwrite',
it should just automatically overwrite it's view...
I'm trying to set up an Extensible Calendar Pro in my ExtJs 4.1 application, but I still get a name is undefined error.
EDIT:
I solved the original problem, but directly went in another.
Updated code:
Ext.define('ZeuS.view.panels.ZeusMainPanel',{
extend: 'Ext.panel.Panel',
id : 'zeusMainPanel',
alias : 'widget.zeus',
requires : [
'Extensible.Extensible',
'Extensible.calendar.CalendarPanel',
'Extensible.calendar.data.MemoryEventStore',
'Extensible.calendar.data.EventModel',
'Extensible.calendar.view.*'
],
autoShow : true,
layout : 'border',
border : false,
initComponent : function(){
this.items = [{
/*
* Some other Ext Elements
*/
}, {
region : 'east',
xtype : 'extensible.calendarpanel',
name : 'zeus-calendar',
width : 500,
eventStore: Ext.create('Extensible.calendar.data.EventStore', {
data: Ext.create('Extensible.calendar.data.EventModel',{
StartDate: '2101-01-12 12:00:00',
EndDate: '2101-01-12 13:30:00',
Title: 'My cool event',
Notes: 'Some notes'
})
})
}
];
this.callParent(arguments);
}
});
Now it loads all classes correctly when the Extensible singleton is included, but nothing works. I just have a white screen and no functions in the controller or anywhere else are called. When I remove it from the requires list it comes up with this error: Extensible.log is not a function
Do I use the plugin at all right?
Any advice?
Extensible.log is defined on the Extensible singleton, so it should always be available if your dependencies and includes are set up correctly. You really should post in the Extensible forums with additonal details (Ext version, Extensible version, script include markup) as this is basically a product support question.
EDIT: By the way, there is no such thing as Extensible.Extensible, which might be part of your problem. Also you cannot use wildcard requires statements for non-Sencha classes. You might try getting a basic example working first before trying to create a complex layout with it.