how i call private block method without create object outside in ext Js? - extjs

Ext.define('App.View.ClassDemo', {
privates: {
runFactory: function () {
this.factory('paresh');
}
},
factory: function (brand) {
alert(brand);
}
});
this class contain privates block and its contain runFactory method how i call this method without creating object outside

With ExtJS you can do something like this:
Ext.define('Computer', {
statics: {
factory: function(brand) {
// 'this' in static methods refer to the class itself
return new this(brand);
}
},
constructor: function() { ... }
});
var dellComputer = Computer.factory('Dell');
The "factory" method is static and can be used without a Computer instance.

Related

How to call a Layout from itself to make an instance

I have a Layout(SubMenu100) that have an event to call other Layout(SubMenu200), but it also make a onClick trigger that will create an instance if layout(SubMenu100) and call itself, but I don't know how to get an instance like the next code.
this.SubMenu100 = new SubMenu100();
I try to put it in Define vars but get me an error.
define([
'backbone.marionette',
'underscore',
'logger',
'tpl!apps/templates/SubMenu100.html',
'i18n!apps/nls/Messages',
'apps/views/SubMenu200',
'apps/views/SubMenu100'
], function (Marionette, _, Logger, Template, i18n, SubMenu200, SubMenu100) {
launch: function (e) {
$("#title_wrapper_div").click(this.callMe);
},
callMe: function () {
if (this.subMenu100 === undefined) {
this.subMenu100 = new SubMenu100(); // <- here
}
window.App.vent.trigger("dashboard:showView",this.subMenu100, "", "", "", "");
}
}
So, this is the question, How can I create an instance of SubMenu100 inside within itself?
If launch is called with context of SubMenu100, you can do this.callMe.bind(this) then you should be able to do new this() inside callMe.
But for simplicity you could do this :
define([
'backbone.marionette',
'underscore',
'logger',
'tpl!apps/templates/SubMenu100.html',
'i18n!apps/nls/Messages',
'apps/views/SubMenu200'
], function(Marionette, _, Logger, Template, i18n, SubMenu200) {
var SubMenu100 = Class SubMenu100 {
launch: function(e) {
$("#title_wrapper_div").click(this.callMe);
},
callMe: function() {
if (this.subMenu100 === undefined) {
this.subMenu100 = new SubMenu100();
}
window.App.vent.trigger("dashboard:showView", this.subMenu100, "", "", "", "");
}
}
return SubMenu100;
});
Note that every launch will create new event handler potentially on the same element (unless something else is doing proper cleanup) and this can lead to bugs. I don't recommend using global jQuery selectors in backbone components.
If you want to create instances of SubMenu100 and SubMenu200 I'd create a higher level component in charge of that:
require([
// ^ ------ this is NOT SubMenu100 definition
'apps/views/SubMenu100',
'apps/views/SubMenu200',
], function (SubMenu100, SubMenu200) {
// this is NOT SubMenu100 definition
launch: function (e) {
$("#title_wrapper_div").click(this.callMe);
},
callMe: function () {
if (this.subMenu100 === undefined) {
this.subMenu100 = new SubMenu100();
}
}
});

angularJS ES6 Directive

I am trying to develop an application in angular es6 . I have a problem with directve.
Here is my code
export default class RoleDirective {
constructor() {
this.template="";
this.restrict = 'A';
this.scope = {
role :"#rolePermission"
};
this.controller = RoleDirectiveController;
this.controllerAs = 'ctrl';
this.bindToController = true;
}
// Directive compile function
compile(element,attrs,ctrl) {
console.log("df",this)
}
// Directive link function
link(scope,element,attrs,ctrl) {
console.log("dsf",ctrl.role)
}
}
// Directive's controller
class RoleDirectiveController {
constructor () {
console.log(this.role)
//console.log("role", commonService.userModule().getUserPermission("change_corsmodel"));
//$($element[0]).css('visibility', 'hidden');
}
}
export default angular
.module('common.directive', [])
.directive('rolePermission',[() => new RoleDirective()]);
The problem is i couldn't get the role value inside constructor.
here is my html implementation
<a ui-sref="event" class="button text-uppercase button-md" role-permission="dfsd" detail="sdfdsfsfdssd">Create event</a>
If i console this it will get the controller object. But it will not get any result while use this.role.
Ok, so I managed to find out how this works.
Basically, the scope values cannot be initialized on the controller's constructor (because this is the first thing executed on a new object) and there is also binding to be considered.
There is a hook that you can implement in your controller that can help you with your use case: $onInit:
class RoleDirectiveController {
constructor () {
// data not available yet on 'this' - they couldn't be
}
$onInit() {
console.log(this.role)
}
}
This should work. Note that this is angular1.5+ way of doing things when not relying on $scope to hold the model anymore. Because if you use the scope, you could have it in the controller's constructor (injected).

Calling angular service from ES6 class method

(Im using Babel to be able to use ES6)
When I call addConfigurationToCart() I get:
ReferenceError: Order is not defined.
But in the constructor I don't. Why is that? I get the same error if I add Order as a parameter to addConfigurationToCart
class ConfigCtrl {
constructor($state, api, Order) {
this.current = Order.current;
}
addConfigurationToCart() {
Order.saveConfiguration();
$state.go('order');
}
}
constructor and addConfigurationToCart functions have different scopes (in JS sense), and sure, the variable from one scope isn't available in another, unless the variable is assigned to either this property or the variable from parent scope.
Private variables are still aren't there in ES2015+, but there are some workarounds to do that.
The most obvious way is using local variables:
let $state, api, Order;
class ConfigCtrl {
static $inject = ['$state', 'api', 'Order'];
constructor(...args) {
[$state, api, Order] = [...args];
// ...
}
addConfigurationToCart() {
Order.saveConfiguration();
// ...
}
}
And more idiomatic approach that successfully provides private variables within class:
const [$state, api, Order] = [Symbol(), Symbol(), Symbol()];
class ConfigCtrl {
static $inject = ['$state', 'api', 'Order'];
constructor(...args) {
[$state, api, Order].forEach((v, i) => this[v] = args[i]);
// ...
}
addConfigurationToCart() {
this[Order].saveConfiguration();
// ...
}
}
You have to make the Service public to the rest of your class.
class ConfigCtrl {
constructor($state, api, Order) {
...
this.Order = Order;
}
addConfigurationToCart() {
this.Order.saveConfiguration();
...
}
}
controller: class {
constructor($http, Restangular, $state) {
Object.assign(this, {$http, Restangular, $state});
}
doIt() {
// use this.$http, this.Restangular & this.$state freely here
}
}

Creating angular base service and sub services

I'm trying to create a general service for dynamic listing objects i angular and for different types of Objects I need slightly different methods for this service. So I thought it would be the best to have a base service and some sub-services. The problem is, that I need to initialize the base service with different Objects depending on sub-service.
So that what I got so far:
Base List-Service (shortened to the relevant)
App.factory('List', ['$q',
function (){
var List = function(Item, searchParams){
this.Item = Item;
this.searchParams = searchParams;
//....
this.nextPage();
};
//.....
List.prototype.nextPage = function () {
//.....
this.Item.find({
//.....
}.bind(this));
};
return List;
}]);
Sub-service of List-Service
App.factory('UserList', [
'User', 'List','$q',
function (User, List) {
UserList = function(){
var searchParams = {
// params Object
};
return new List(User, searchParams);
};
// extend base class:
UserList.prototype.updateUser = function(id){
//.....
}
//....
return UserList;
}]);
Currently just the UserList is loaded, but: Of course it loads every time a new instance, due the new operator when it's called, but I just want one instance. But leaving the new operator throw's an error that this.nextPage(); would be undefined function. Beside this it seems the extension function updateUser is not applied.
So what's the best practice to inherit from other service with passing arguments to parent service in angular?
I gotta work it.
changed sub service to this to inherit proper from base:
App.factory('UserList', [
'User', 'List','$q',
function (User, List) {
var UserList = function(){
var searchParams = {
//.....
};
List.call(this, User, searchParams);
};
// inherit from List service
UserList.prototype = Object.create(List.prototype);
UserList.prototype.updateUser = function(id) {
//.....
};
return UserList;
}
])
;

Angular and Typescript Memory leaks

In a AngularJS 1.2.5 using TypeScript 0.9.1 app, we are seeing that when we change routes, the private methods on a controller class remain in the heap and leave detached DOM trees in chromes profiler.
If we navigate /#/view1 to /#/view2 and back to /3/view1, we end up with view1 controller class in the heap twice and view2 controller class in the heap as well.
Our workaround has been to not use private methods anymore.
The code generally looks like:
module views {
app.controller("view1Ctrl", function($scope, $routeParams) {
return new view1Ctrl($scope, $routeParams);
});
interface Scope extends ng.IScope {
TrackingTab: any;
}
class view1Ctrl {
constructor(private $scope: Scope, $routeParams: any) {
$scope.TrackingTab = $routeParams["tab"];
$scope.$watch("showTab", (newValue: TrackingTab): void => {
if (newValue === undefined) return;
});
}
private changeTabToNew(): void {
this.$scope.TrackingTab = "new"
}
}
}
we have to change to something along the lines of:
module views {
app.controller("view1Ctrl", function($scope, $routeParams) {
return new view1Ctrl($scope, $routeParams);
});
interface Scope extends ng.IScope {
TrackingTab: any;
}
class view1Ctrl {
constructor(private $scope: Scope, $routeParams: any) {
$scope.TrackingTab = $routeParams["tab"];
$scope.$watch("showTab", (newValue: TrackingTab): void => {
if (newValue === undefined) return;
});
$scope.changeTabToNew(): void {
this.$scope.TrackingTab = "new"
};
}
}
Thanks in advance
If you want to make functions private in javascript, please refer to:
http://javascript.crockford.com/private.html
From the above code I think that the code:
private changeTabToNew(): void {
this.$scope.TrackingTab = "new"
}
is simply creating a function changeTabToNew() on the global (or root) scope (the private keyword is not having the effect you are expecting btw). Since this is not part of the scope that exists in the controller, you are creating a reference to your 'TrackingTab' in global scope and thus the controller cannot be garbage collected.

Resources