EXT JS 5 - Override ViewController definition? - javascript

I want all my ViewControllers to have two custom methods.
I tried to accomplish this by creating a class that extends from the ViewController, called CustomViewController, and then having my other ViewControllers extend my CustomViewController class, but then I get a warning message in the console saying:
[W] Overriding existing mapping: 'controller.login' From 'MyApp.view.mybutton.MyButtonController' to 'MyApp.view.override.CustomViewController'. Is this intentional?
And the component I tested it with didn't even load.
I realize I could do this straight from the ext-all-debug.js library that's inside the ext folder in my app's root folder, but then when I use Sencha CMD to build the app it'll use my original library that's in my workspace, and not the one I have in my app's folder, so my changes will only work while developing and won't carry on to production.
What's the proper way of doing this? Is there a standard?

That error probably means that you have the same alias config on both Eathisa.view.login.loginController and Eathisa.view.override.EathisaViewController. There will be some ambiguity as to which class to load when you try to use it by an alias, that is why the class system is warning you.
From what you describe it doesn't sound like you need an override at all. If you need to have some methods in all your ViewControllers, you can add them in a custom ViewController and then use it as a base for all other ViewControllers in your application, instead of Ext.app.ViewController:
Ext.define('Eathisa.view.AbstractViewController', {
extend: 'Ext.app.ViewController',
// Note that there is no "alias" property here, so that
// this abstract VC can't be instantiated by alias
// You can even make these custom methods excluded from
// production build by enclosing them in the <debug></debug>
// comment brakets:
//<debug>
methodFoo: function() {
...
}
//</debug>
});
Ext.define('Eathisa.view.login.LoginController', {
extend: 'Eathisa.view.AbstractViewController',
alias: 'controller.login',
methodThatUsesFoo: function() {
// Just don't forget to enclose the code that *calls*
// debug-only methods in the same <debug> brackets
//<debug>
this.methodFoo();
//</debug>
...
}
});
If it's not feasible to extend all your ViewControllers from the same abstract VC, implement the custom methods in a mixin instead, and include that mixin in the VCs that need debug methods:
Ext.define('Eathisa.mixin.Debug', {
methodFoo: function() {
...
}
});
Ext.define('Eathisa.view.login.LoginController', {
extend: 'Ext.app.ViewController',
alias: 'controller.login',
// Conditionally include the debugging mixin
//<debug>
mixins: [
'Eathisa.mixin.Debug'
],
//</debug>
...
});

Related

Nuxtjs custom module

I'm quite new to Nuxtjs so I made a test project which purpose is merely the (of course) testing of Nuxtjs functionalities.
Currently I'm trying to create a simple custom module: afaik a module is basically a wrapper around a vou/js library/plugin, something like a high-level integration used to expose configurations on how the underlying library/plugin is imported and used in the Nuxt application.
So I'm trying with a simple module that declare some plain js classes that I'll use in my application, e.g. Order and Product, and that's what I came out with:
Directory structure
pages
the-page.vue
modules
classes
index.js
order.js
/modules/classes/index.js
const path = require('path')
export default function (moduleOptions) {
const { nuxt } = this
// add the debug plugin
this.addPlugin({
src: path.resolve(__dirname, 'order.js'),
})
}
/modules/classes/order.js
class Order {
constructor(id) {
this.id = id;
console.log('created order #' + this.id);
}
}
export {Order};
/nuxt.config.js
export default {
// ...
buildModules: [
// ...
'~/modules/classes'
],
// ...
}
/pages/the-page.vue
<script>
export default {
name: 'ThePage',
data () {
return {
}
},
methods: {
createOrder () {
const order = new Order(123)
}
}
}
</script>
The error
My defined class are still not imported in my pages:
/app/pages/the-page.vue
18:13 error 'order' is assigned a value but never used no-unused-vars
18:25 error 'Order' is not defined no-undef
Considerations
Probably I'm missing something about modules usage and/or implementation, but every tutorial I found starts with too complex scenarios, and since I'm at the beginning with Nuxtjs I need something easier to implement.
Ok, I found out that I was mistaken how NuxtJs modules are intended to work and was traying to do somenthing they are not intended for.
Nuxt modules cannot import js classes in every component of the application as I wanted to do, they just "add a property" to the main application instance that is made accessible through this.$<something>, like e.g. you can already do in simple Vue with the Vue Router or the Vuex store plugins that give access to the this.$router and this.$store properties.
NuxtJs modules just wrap simple plugins and expose configuration options to made.

Where to store common component methods in #NUXT.JS

Actually i want to know where to store common components methods in #NUXT.JS.
things which i have tried.
--> Storing common code in middleware (its use-less) because according to my knowledge middleware is only capable of handling request and response to server.
methods: {
// states methods.
SwitchManager: function (__dataContainer, __key, __value) {
// stand alone debugger for this module.
let debug = __debug('computed:_3levelSwitch')
// debug showing function loaded.
debug('(h1:sizeCheck) creating switch..')
// switch.
switch (__key) {
// fake allow set value to true of given key
default:
this[__dataContainer][__key][__value] = true
break
}
return this[__dataContainer][__key][__value]
},
SizeCheck: function (__size) {
// stand alone debugger for this module.
let debug = __debug('tags:p')
// debug showing function loaded.
debug('(p:sizeCheck) checking..')
// init switch.
this.SwitchManager('pill', 'size', __size)
},
StateCheck: function (__state) {
// stand alone debugger for this module.
let debug = __debug('tags:h1')
// debug showing function loaded.
debug('(h1:sizeCheck) checking..')
// init switch.
this.SwitchManager('pill', 'state', __state)
}
},
created () {
// h1 tag size check
this.SizeCheck(this.size)
this.StateCheck(this.state)
}
I go for mixins like with plain vue.js. Only difference - for global mixins - I include them as a plugin, but first:
Non global mixins
I would create an extra folder for my mixins. For example in a /mixins/testMixin.js
export default {
methods: {
aCommonMethod () {}
}
}
Then import in a layout, page or component and add it via the mixins object:
<script>
import commonMixin from '~/mixins/testMixin.js'
export default {
mixins: [commonMixin]
}
</script>
Global mixins
For example in a new file plugins/mixinCommonMethods.js:
import Vue from 'vue'
Vue.mixin({
methods: {
aCommonMethod () {}
}
})
Include that file then in nuxt.config.js
plugins: ['~/plugins/mixinCommonMethods']
After that you would have the method everywhere available and call it there with this.commonMethod(). But here an advice from the vue.js docs:
Use global mixins sparsely and carefully, because it affects every single Vue instance created, including third party components. In most cases, you should only use it for custom option handling like demonstrated in the example above. It’s also a good idea to ship them as Plugins to avoid duplicate application.
Inject in $root & context
Another possibility would be to Inject in $root & context

Leading Underscore transpiled wrong with es6 classes

I am experiencing a really weird behavior and can't even say which package to blame for it.
My setup: RequireJS project with the JSXTransformer and the jsx! plugin
I have an es6 class like this:
define([
'react'
], function(
React
) {
class MyComponent extends React.Component {
myMethod() {
otherObject.someMethod()._privateProp; // Yes, we need this accessing and have no influence on it
}
}
return MyComponent;
});
The transpiled output in the resulting bundle after running r.js is:
define('jsx!project/components/InputOutput',[
'react'
], function(
React
) {
var ____Class8=React.Component;for(var ____Class8____Key in ____Class8){if(____Class8.hasOwnProperty(____Class8____Key)){MyComponent[____Class8____Key]=____Class8[____Class8____Key];}}var ____SuperProtoOf____Class8=____Class8===null?null:____Class8.prototype;MyComponent.prototype=Object.create(____SuperProtoOf____Class8);MyComponent.prototype.constructor=MyComponent;MyComponent.__superConstructor__=____Class8;function MyComponent(){"use strict";if(____Class8!==null){____Class8.apply(this,arguments);}}
MyComponent.prototype.myMethod=function() {"use strict";
otherObject.someMethod().$MyComponent_privateProp;
};
return MyComponent;
});
Note how otherObject.someMethod().$MyComponent_privateProp; is written there. This obviously breaks because it is not a property on instances of MyComponent.
Add /** #preventMunge */ to the top of the file. See this GitHub issue:
Yes, sorry this is a non-standard fb-ism. For now you can work around this and toggle this feature off by putting /** #preventMunge */ at the top of your file -- but that's also a pretty big fb-ism. We should (a) turn this into a transform option (rather than a direct docblock directive) and (b) make it opt-in rather than opt-out (since it's non-standard).
For context: We munge all under-prefixed object properties on a per-module basis partly because our under-prefix convention applies to both objects and classes. Additionally, even if we wanted to lax the objects vs classes distinction, it's impossible to tell (in the general case) if a property is a reference to this since alias variables can occur (i.e. var self = this; self._stuff;).

How to share objects/methods between controllers without circular references?

Pretty straightforward question. Currently, what I do when I need to access objects' methods throughout most of the application, I do this in app.js
Ext.define('Utils', {
statics: {
myMethod: function() {
return 'myResult';
}
}
});
This works, but when I build the application, I get a warning about a circular reference (app.js of course needs all the other controller classes, but then said classes refer back to app.js).
I thought of using a package including a .js file that has all the objects/methods, but sometimes, within these methods I'll need access to the Ext namespace so that won't work.
Is there any better way to do this ?
Thanks!
You should not define the class Utils inside app.js. Each Ext.define statement should be in it's own file. Also the classname should be prefixed with your app name.
Ext.define('MyApp.Utils', {
statics: {
myMethod: function() {
return 'myResult';
}
}
});
should therefore be found in the file app/Utils.js. When compiling your sources into a compiled app.js, Sencha Cmd will take care of the proper ordering in the final file. The requires and uses directives give you enough flexibility to define any dependences between your classes.
Read all the docs about MVC to get a clear understanding.

Load prototype enhancements with require.js

I am using require.js to load my modules which generally works fine. Nevertheless, I do have two additonal questions:
1) If you have a module that is like a helper class and defines additional methods for existing prototypes (such as String.isNullOrEmpty), how would you include them? You want to avoid using the reference to the module.
2) What needs to be changed to use jQuery, too. I understand that jQuery needs to be required but do I also need to pass on $?
Thanks!
1) If you have a module that is like a helper class and defines
additional methods for existing prototypes (such as
String.isNullOrEmpty), how would you include them? You want to avoid
using the reference to the module.
If you need to extend prototypes then just don't return a value and use it as your last argument to require:
// helpers/string.js
define(function() {
String.prototype.isNullOrEmpty = function() {
//
}
});
// main.js
require(['moduleA', 'helpers/string'], function(moduleA) {
});
2) What needs to be changed to use jQuery, too. I understand that
jQuery needs to be required but do I also need to pass on $?
The only requirement for jQuery is that you configure the path correct
require.config({
paths: {
jquery: 'path/to/jquery'
}
});
require(['jquery', 'moduleB'], function($, moduleB) {
// Use $.whatever
});
In my opinion it's unnecessary to use the version of RequireJS that has jQuery built into it as this was primarily used when jQuery didn't support AMD.
Nowadays it does and keeping it separate allows you to swap another library out easily (think Zepto).
2/ For jquery it's really simple :
require(["jquery", "jquery.alpha", "jquery.beta"], function($) {
//the jquery.alpha.js and jquery.beta.js plugins have been loaded.
$(function() {
$('body').alpha().beta();
});
});
More information on require site : http://requirejs.org/docs/jquery.html#get
1/ in my devs for such extension I did it in a global file without require module code.... and I include it in my app with require... not perfect, but it's work fine
global.js
myglobalvar ="";
(...other global stuff...)
myapp.js
// Filename: app.js
define([
(...)
'metrix.globals'
], function(.....){
myApp = {
(...)

Categories