ExtJS4: Accessing global variables from Ext.Application - extjs

I want to load some application specific settings and save them as global variables when the application is loaded. I have found how to create and access global variable here.
This is how my app.js looks like:
Ext.application({
stores: [
...
],
views: [
...
],
autoCreateViewport: true,
name: 'MyApp',
controllers: [
'DefaultController'
],
launch: function() {
...
}
});
Is it possible to set these variables inside launch: function() block? If not, are there any alternatives?

You can also create a singleton:
Ext.define('MyApp.util.Utilities', {
singleton: true,
myGlobal: 1
});
in your app:
Ext.application({
stores: [
...
],
views: [
...
],
autoCreateViewport: true,
name: 'MyApp',
controllers: [
'DefaultController'
],
requires: ['MyApp.util.Utilities'], //Don't forget to require your class
launch: function() {
MyApp.util.Utilities.myGlobal = 2; //variables in singleton are auto static.
}
});

Related

Unit test an angular service (not factory) using Jasmine

I've been trying to test an Angular service using Jasmine following tutorials, but for some reason their examples don't here works (they suggest injecting services using the angular.mock.inject() method)...
This is the way I got it working, but I am afraid this is not how it should be done...
Is this "good practice"? Why injecting doesn't work?
I basically import the service into the test, setup my module and $provide the service's dependencies, and new the service passing it what would normally be injected...
Anyway, here it is:
import rolesService from './roles.service.js';
describe('Roles', () => {
let RolesService;
let PermRoleStore;
let USER;
beforeEach(() => {
angular.mock.module('roles', ($provide) => {
$provide.constant('USER', {
roles: ['SOUTIEN_ORGANISME']
});
$provide.value('PermRoleStore', {
defineManyRoles: jasmine.createSpy(),
});
});
angular.mock.inject((_PermRoleStore_, _USER_) => {
PermRoleStore = _PermRoleStore_;
USER = _USER_;
RolesService = new rolesService(PermRoleStore, USER);
});
});
it('Setup should define the roles', () => {
RolesService.setup();
expect(PermRoleStore.defineManyRoles).toHaveBeenCalled();
});
describe('authorize', () => {
it('should return true if authorized', () => {
expect(RolesService.authorize('SOUTIEN_ORGANISME')).toBe(true);
});
it('should return false if the user it NOT authorized', () => {
expect(RolesService.authorize('NOT_AUTHORIZED')).toBe(false);
});
});
});
Here is the karma.config.js file just for reference:
'use strict';
const stringify = require('stringify');
const babelify = require('babelify');
module.exports = (config) => {
config.set({
basePath: '',
frameworks: ['browserify', 'jasmine-ajax', 'jasmine'],
files: [
{ pattern: 'build/gouvernementales/app-gouvernementales.config.json', watched: true, served: true, included: false },
'build/gouvernementales/js/gouvernementales-libs.js',
'src/apps/gouvernementales/app-gouvernementales.js',
'src/apps/gouvernementales/**/*.spec.js',
'src/modules/**/*.spec.js',
],
preprocessors: {
'src/apps/gouvernementales/app-gouvernementales.js': 'browserify',
'src/apps/gouvernementales/**/*.spec.js': 'browserify',
'src/modules/**/*.spec.js': 'browserify',
},
browsers: ['PhantomJS'],
plugins: [
'karma-phantomjs-launcher',
// 'karma-chrome-launcher',
'karma-jasmine-ajax',
'karma-jasmine',
'karma-browserify',
'karma-coverage',
'karma-mocha-reporter',
],
browserify: {
debug: true,
transform: [
babelify,
stringify,
],
},
helpers: [
'src/spec/helpers/**/*.js',
],
reporters: [
'mocha',
'coverage',
],
coverageReporter: {
dir: 'coverage/',
reporters: [
{ type: 'text-summary' },
{ type: 'html' },
],
},
logLevel: config.LOG_DEBUG,
singleRun: false,
colors: true,
autoWatch: true,
});
};
You don't need to do like this one
import rolesService from './roles.service.js'; // it should be not included.
//Should be injected
BEFOREEACH
beforeEach(() => {
angular.mock.module(($provide) => {
$provide.constant('USER', {
roles: ['SOUTIEN_ORGANISME']
});
$provide.value('PermRoleStore', {
defineManyRoles: jasmine.createSpy(),
});
});
//you are mocking PermRoleStore and USER,so should be inject it here.
//It will get available to your service
//no need of import
angular.mock.inject((_rolesService_) => {
PermRoleStore = _rolesService_;
});
});

angularjs requirejs karma directive templateUrl test fail

question
I replace templateUrl with template in author-signature.js, then I test success.
But I use templateUrl way in author-signature.js, I test fail. I watch files loading and chrome debug, author-signature.html did translate to js, and html content did exist in $templateCache too, but I test fail. Printscreen:
author-signature.html.js
$templateCache debug content
filepath
--public
----scripts
--------**/*.js
--test
----**/*.js
--views
----templates
--------**/*.html
test-main.js
require.js main entry file
var allTestFiles = [];
var TEST_REGEXP = /(\-test)\.js$/i;
Object.keys(window.__karma__.files).forEach(function (file) {
if (window.__karma__.files.hasOwnProperty(file)) {
if (TEST_REGEXP.test(file)) {
allTestFiles.push(file);
}
}
});
require.config({
baseUrl: '/base/public/scripts',
paths: {
'jquery': '../libs/jquery/dist/jquery',
'angular': '../libs/angular/angular',
'angularMocks': '../libs/angular-mocks/angular-mocks',
'templates': '../../views/templates'
},
shim: {
'angular': {
deps: ['jquery'],
exports: 'angular'
},
'angularMocks': {
deps: ['angular'],
exports: 'angular.mock'
},
'templates/default/author-signature.html': ['angular']
},
deps: allTestFiles,
callback: window.__karma__.start
});
karma.conf.js
karma configuration file, I translate js to html by ng-html2js
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', 'requirejs'],
files: [
{pattern: 'public/libs/jquery/dist/jquery.js', included: false},
{pattern: 'public/libs/angular/angular.js', included: false},
{pattern: 'public/libs/angular-mocks/angular-mocks.js', included: false},
{pattern: 'public/scripts/**/*.js', included: false},
{pattern: 'views/templates/**/*.html', included: false},
{pattern: 'test/**/*-test.js', included: false},
'test/test-main.js'
],
exclude: [
'public/scripts/build-main.js',
'public/scripts/require-config.js',
'public/scripts/bootstrap.js'
],
browsers: ['Chrome'],
reporters: ['progress', 'html', 'coverage'],
htmlReporter: {
outputFile: 'report/units.html',
pageTitle: 'Unit Tests',
subPageTitle: 'Unit tests with karma jasmine'
},
preprocessors: {
'public/scripts/**/*.js': ['coverage'],
'views/templates/**/*.html': ['ng-html2js']
},
coverageReporter: {
type: 'html',
dir: 'report/coverage/'
},
ngHtml2JsPreprocessor: {
stripPrefix: 'views/',
stripSuffix: '.html',
moduleName: 'templates'
}
});
}
author-signature-test.js
directive test file
define(['angularMocks', 'directives/default/author-signature', 'templates/default/author-signature.html'], function () {
describe('Unit: Hello Directive', function () {
var $compile, $rootScope;
beforeEach(function () {
module('angularApp');
module('templates');
inject(function (_$compile_, _$rootScope_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
});
});
it('should display the hello text properly', function () {
var elt = $compile('<author-signature author="Plus"></author-signature>')($rootScope);
expect(elt.text()).toEqual('Plus');
});
});
});
author-signature.js
simply directive file
define('directives/default/author-signature', [
'angular-app'
], function (angularApp) {
angularApp.directive('authorSignature', function () {
return {
restrict: 'EA',
scope: {
author: '#'
},
replace: true,
templateUrl: 'templates/default/author-signature'
};
});
});
author-signature.html
<h1>{{author}}</h1>
angular-app.js
define('angular-app', [
'angular'
], function (angular) {
var angularApp = angular.module('angularApp', []);
return angularApp;
});
OMG, I forget add $rootScope.$digest(); in test directive.
That cause this directive scope's attributes doesn't change.

AngularJS Configuration Structure

I want to summarize all module configurations within a block and it doesn't work and I don't get any error message.
The following works:
angular.module('myApp', [
'ngRoute',
'oc.lazyLoad',
'myApp.login',
]).
config(
[
'$routeProvider', function($routeProvider) {
$routeProvider
.otherwise({redirectTo: '/login'});
}
]
);
angular.module('myApp').config(
function($ocLazyLoadProvider) {
$ocLazyLoadProvider.config(
{
modules: [{
name: 'icons_and_fonts',
files: [
'components/font-awesome/css/font-awesome.min.css',
'components/weather-icons/css/weather-icons.min.css'
]
}],
debug: true,
events: true
});
}
);
But if I want to integrate $ocLazyProvider into the configuration block above, it doesn't work, the following code does not work:
config(
[
'$routeProvider', function($routeProvider) {
$routeProvider.otherwise({redirectTo: '/login'});
}
],
[
'$ocLazyLoadProvider', function($ocLazyLoadProvider) {
$ocLazyLoadProvider.config(
{
modules: [{
name: 'icons_and_fonts',
files: [
'components/font-awesome/css/font-awesome.min.css',
'components/weather-icons/css/weather-icons.min.css'
]
}],
debug: true,
events: true
}
)
}
]
);
What could be the problem?
You should pass a single array/function into the config block, instead of multiple. you can perform both configurations in a single function, that would look something like:
config(['$routeProvider','$ocLazyLoadProvider',function($routeProvider,$ocLazyLoadProvider) {
$routeProvider.otherwise({redirectTo: '/login'});
$ocLazyLoadProvider.config(
{
modules: [{
name: 'icons_and_fonts',
files: [
'components/font-awesome/css/font-awesome.min.css',
'components/weather-icons/css/weather-icons.min.css'
]
}],
debug: true,
events: true
}
)
}
]
);

loading modules and factories files using angular ui routing and ocLazyLoad

i', using angular ui routing with ocLazyLoad to load the appendices files according to the choosen stat as the following code shows
my problem is:
when i load a new state and click refresh sometime the factories is not initialized -i think it's because the files is not fully loaded before init the controller-
i also tried to merge all files in the same ocLazyLoad function and use serie : true but dosenot work
is it the right use of ocLazyLoad
i've the following modules
angular.module('app', [ "oc.lazyLoad"]);
angular.module("app.inventory", []);
angular.module("app.sales", []);
and here is the routing
.state("invoicesAddEdit", {
url: "/invoice/:invoiceId",
templateUrl: "app/components/sales/invoice/views/invoiceAddEdit.view.html",
controller: "InvoiceAddEditController",
resolve: {
invoiceId: ['$stateParams', function ($stateParams) {
return $stateParams.invoiceId;
}],
settings: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load({
name: "app.settings",
files: [
"app/components/settings/settings.module.js",
"app/components/settings/currency/services/currency.factory.js",
"app/components/settings/deliveryMan/services/deliveryMan.factory.js",
]
})
}],
inventory: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load({
name: "app.inventory",
files: [
"app/components/inventory/inventory.module.js",
"app/components/inventory/customer/services/customer.factory.js",
"app/components/inventory/store/services/store.factory.js",
"app/components/inventory/product/services/product.factory.js",
]
})
}],
purchasing: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load({
name: "app.purchasing",
files: [
"app/components/purchasing/purchasing.module.js",
"app/components/purchasing/purchaseOrder/services/purchaseOrder.factory.js",
]
})
}],
sales: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load({
name: "app.sales",
files: [
"app/components/sales/sales.module.js",
"app/components/sales/representative/services/representative.factory.js",
"app/components/sales/invoice/services/invoice.factory.js",
"app/components/sales/invoice/controllers/invoiceAddEdit.controller.js",
]
})
}],
}
})
Try to inject the oCLazy Load as deps and insert the required files before specific tag in the html like the following :
resolve: {
invoiceId: ['$stateParams', function ($stateParams) {
return $stateParams.invoiceId;
}],
deps: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load({
name: "app.settings",
insertBefore: '#ng_load_plugins_before',
files: [
"app/components/settings/settings.module.js",
"app/components/settings/currency/services/currency.factory.js",
"app/components/settings/deliveryMan/services/deliveryMan.factory.js",
]
})
}],
Add the following link to the header of the html page or the View:
<link id="ng_load_plugins_before"/>

Why is Sencha Cmd not adding most of my ExtJS 4.2 app into app.js

I wonder if this is because we don't have this app structure:
MyApp
/app
/controller
/model
/store
/view
But instead we have this app structure:
MyApp
/app
/feature1
/controller
/model
/store
/view
/feature2
/controller
/model
/store
/view
Here is a sample define:
Ext.define('base.model.Job', {
Here is from app.js
Ext.application({
name: 'AMC',
appFolder: 'app',
requires: [
'base.model.Job',
I'm looking into using Sencha Cmd 4.0.2.67. I generated a skeleton app with generate, created a workspace and a package, and sencha app build runs fine, no errors or warnings.
But when I look in the /workspace/build/production/AMC/ folder, minified app.js has only 19 Ext.define, but my app has at least 250 Ext.define for all my classes.
I thought when I define app.js in my dev environment, dependencies would be resolved, and all mode code would be minified and put in app.js in production.
Here is an example of my app.js in my dev enviroment:
Ext.Loader.setConfig({
enabled : true
});
Ext.application({
name: 'AMC',
appFolder: 'app',
requires: [
'atlas.model.Pool',
'atlas.model.Volume',
'base.model.Job',
'atlas.model.Performance',
'atlas.utilities.CommonUtil',
'atlas.utilities.CommonVTypes'
],
views: [
'atlas.view.login.Login'
],
controllers: [
'atlas.wizard.impl.hanode.controller.WizardHaNodeController',
'atlas.wizard.impl.agg.controller.WizardAggController',
'atlas.wizard.impl.disk.controller.WizardDiskController',
'atlas.wizard.impl.mem.controller.WizardMemController',
'atlas.wizard.impl.ads.controller.WizardAdsController',
'atlas.wizard.base.controller.WizardReviewController',
'atlas.wizard.base.controller.WizardWindowController',
'atlas.wizard.base.controller.WizardPanelController',
'atlas.wizard.base.controller.WizardFormTypeTierController',
'atlas.wizard.base.controller.WizardFormTypeOptimizeController',
'atlas.wizard.base.controller.WizardFormTypeInMemoryController',
'atlas.wizard.base.controller.WizardFormTypeMemoryPureController',
'atlas.wizard.base.controller.WizardLookupDataStoreController',
'atlas.wizard.base.controller.WizardLookupImportsController',
'atlas.wizard.base.controller.WizardLookupHostDatastoreController',
'atlas.controller.ha.HaNodeController',
'atlas.controller.portlet.GraphiteController',
'atlas.controller.setting.VcenterController',
'atlas.controller.setting.SettingController',
'atlas.controller.PerspectiveController',
'atlas.controller.cluster.AssignVolumeToClusterController',
'atlas.controller.cluster.AssignPoolToClusterController',
'atlas.controller.login.LoginController',
'atlas.controller.ha.DeleteHAConfigController',
'atlas.controller.ha.CreateHAConfigController',
'atlas.controller.pool.AddAggregatorToPoolController',
'base.controller.HeaderLinkController',
'atlas.wizard.base.controller.WizardOptionsController',
'base.controller.task.TaskListController',
'base.controller.TabPanelController',
'atlas.controller.cloud.CloudGettingStartedController',
'atlas.controller.cloud.CloudOverviewController',
'atlas.controller.aggregator.AggregatorHostListController'
],
models: [
'atlas.model.Pool',
'atlas.model.Volume',
'base.model.Job',
'atlas.model.Performance',
'base.model.Task'
],
stores: [
'atlas.wizard.base.store.WizardHaConfigStore',
'atlas.store.PerformancePoolTypeStore',
'atlas.store.PerformanceVolumeTypeStore',
'atlas.store.PerformanceChartTypeStore',
'atlas.store.TimeRangeStore'
],
init: function()
{
var me = this;
me.setRestWebServiceUrl();
delete Ext.tip.Tip.prototype.minWidth;
// This statement is disabling browser default context menu when right-clicking in ExtJS.
Ext.getBody().on("contextmenu", Ext.emptyFn, null, {preventDefault: true});
},
launch: function()
{
//Ext.create('atlas.view.login.LoginForm');
Ext.create('atlas.view.login.Login');
//Ext.create('atlas.view.Viewport');
},
onAddController : function(index, controller, key)
{
controller.init(this);
},
getPerspective: function()
{
return this.perspective;
},
getPerspectiveId: function()
{
return this.perspectiveId;
},
getPerspectiveController : function()
{
return this.getController('atlas.controller.PerspectiveController');
}
});

Resources