In TypeScript I have this simple code:
namespace Customer {
function onOpen() {
}
}
It generates:
var Customer;
(function (Customer) {
function onOpen() {
}
})(Customer || (Customer = {}));
In order for Kendo to use onOpen the JS needs to look like this (Notice the onOpen). Is this possible?:
var Customer;
(function (Customer) {
Customer.onOpen = function () {
}
})(Customer || (Customer = {}));
Add export:
namespace Customer {
export function onOpen() {
}
}
Produces:
var Customer;
(function (Customer) {
function onOpen() {
}
Customer.onOpen = onOpen;
})(Customer || (Customer = {}));
You need to export exposed properties, and since functions are first class citizens, you can write typescript code like this :
namespace Customer {
export const onOpen = () => {}
}
Or instead of a lambda just with normal function
namespace Customer {
export const onOpen = function() {}
}
Or this will work
namespace Customer {
export function onOpen() { }
}
That will generate a property that points to a function instead of a function member - essentially the same thing really.
Javascript output:
var Customer;
(function (Customer) {
Customer.onOpen = function () { };
})(Customer || (Customer = {}));
Related
I am facing an issue with typescript build while trying to wrapper multiple classes into a single function.
Below is the sample code.
// AppState.ts
export class AppState {
static id: string;
}
// AppLogic.ts
import { AppState } from './AppState'
export class AppLogic{
constructor(id : string){
AppState.id = id;
}
public getAppID() : string{
return AppState.id;
}
}
// main.ts
import { AppLogic } from './AppLogic';
export function AppwrapAPI(id : string): any{
class AppAPI{
private app : AppLogic;
constructor(id : string){
this.app = new AppLogic(id);
}
public getAppID() : string{
return this.app.getAppID();
}
}
return new AppAPI(id);
}
<!DOCTYPE html>
<html>
<head>
<title>Test app</title>
</head>
<body>
<script type="module">
import { AppwrapAPI } from "./dist/main.es.js";
let a1 = new AppwrapAPI("123");
alert(a1.getAppID()); ///"123"
let a2 = new AppwrapAPI("321"); ///"321"
alert(a2.getAppID());
alert(a1.getAppID()); ///"321" <<--- wrong data
</script>
</body>
</html>
The above ts project generates the following js code using rollup built.
var AppState = /** #class */ (function () {
function AppState() {
}
return AppState;
}());var AppLogic = /** #class */ (function () {
function AppLogic(id) {
AppState.id = id;
}
AppLogic.prototype.getAppID = function () {
return AppState.id;
};
return AppLogic;
}());function AppwrapAPI(id) {
var AppAPI = /** #class */ (function () {
function AppAPI(id) {
this.app = new AppLogic(id);
}
AppAPI.prototype.getAppID = function () {
return this.app.getAppID();
};
return AppAPI;
}());
return new AppAPI(id);
}export{AppwrapAPI};//# sourceMappingURL=main.es.js.map
In this code, the AppwrapAPI function wraps only the AppAPI function instead of all the functions and the AppState function is outside the AppwrapAPI function which creates an issue when I create multiple instances for the AppwrapAPI function.
let a1 = new AppwrapAPI("123");
alert(a1.getAppID()); ///"123"
let a2 = new AppwrapAPI("321"); ///"321"
alert(a2.getAppID());
alert(a1.getAppID()); ///"321" <<--- wrong data
I want to wrapper all the three classes AppState, AppLogic, AppAPI inside the AppwrapAPI function so that the AppState is not shared between the multiple instances.
Similar to the below code
"use strict";
function AppwrapAPI(id) {
class AppState {
}
class AppLogic {
constructor(id) {
AppState.id = id;
}
getAppID() {
return AppState.id;
}
}
class AppAPI {
constructor(id) {
this.app = new AppLogic(id);
}
getAppID() {
return this.app.getAppID();
}
}
return new AppAPI(id);
}
let a1 = AppwrapAPI("123");
console.log(a1.getAppID()); /// output : 123
let a2 = AppwrapAPI("321");
console.log(a2.getAppID()); /// output : 321
console.log(a1.getAppID()); /// output : 123
Right now I manually modifying the generated code to avoid this issue but it gives me some other issue while debugging with the source map generated from the old file.
Can anyone suggest to me how to modify the typescript code to get the single function that wraps all the classes in the typescript project?
Hi i have parent module like this.
// usermgmt.js
var usermgmt = function () {};
usermgmt.prototype.test = function () {
return "test";
};
usermgmt.private = function () {
return "private";
};
module.exports = new usermgmt();
and a Child prototype class like this.
// authentication.js
var usermgmt = require('./usermgmt');
var authentication = function () {};
authentication.prototype.callParent = function () {
usermgmt.private();
};
module.exports = new authentication();
How i implement inheritance? I searched by google but no solution works for me.
Here's a typical way to export a base class and then import it and inherit from it using the more modern syntax:
// a.js
class A {
constructor() {
}
testA() {
return "testA";
}
}
module.exports = A;
Then, in a separate file:
// b.js
const A = require('./a.js');
class B extends A {
constructor() {
super();
}
testB() {
return "testB";
}
}
let x = new B();
x.testA(); // "testA" - this is inherited obviously
x.testB(); // "testB"
As #jfriend00 said, I write these functions with class keyword which is a syntactic sugar for your code!
usermgmt.js
// usermgmt.js
class usermgmt {
constructor() {
}
test() {
return "test";
}
private() {
return "private";
}
}
module.exports = usermgmt;
Write authentication like this.
authentication.js
// authentication.js
var Usermgmt = require('./usermgmt.js');
class authentication extends Usermgmt {
constructor() {
super();
}
callParent() {
console.log(this.private());
}
authFunction() {
console.log(':: authFunction ::');
this.callParent();
}
}
module.exports = authentication;
And usage for authentication will be:
var Authentication = require('./authentication.js');
let auth = new Authentication();
auth.callParent();
auth.authFunction();
console.log(auth.test());
1) Use class and extends syntax which is easier.
2) Return Class and not its instance
var app = angular.module('testApp', []);
class Component {
constructor(app, name, template, as, bindings) {
this.bindings = bindings;
this.config = {}
this.config.template = template;
this.config.controllerAs = as;
// pre-create properties
this.config.controller = this.controller;
this.config['bindings'] = this.bindings;
app.component(name, this.config);
console.log("Inside Component ctor()");
}
addBindings(name, bindingType) {
this.bindings[name] = bindingType;
}
controller() {
}
}
class App extends Component {
constructor(app) {
var bindings = {
name: "<"
};
super(app, "app", "Hello", "vm", bindings);
}
controller() {
this.$onInit = () => this.Init(); // DOESN'T WORK
/*
var self = this;
self.$onInit = function () { self.Init(); }; // DOESN'T WORK
*/
/*
this.$onInit = function () { // WORKS
console.log("This works but I don't like it!");
};
*/
}
Init() {
console.log("Init");
}
onNameSelected(user) {
this.selectedUser = user;
}
}
var myApp = new App(app);
<div ng-app="testApp">
<app></app>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.js"></script>
I'm trying to "classify" angular 1.5's .component(). I can get most of it figured out but when I try to assign a class method for $onInit it doesn't work. I've tried assigning to it and using arrow notation to call back to the class method but neither work. It does work if I assign an anonymous function directly but I don't want to do that. I want those functions to point to class methods because I find it cleaner.
So ultimately I want my App classes Init() method to get called for $onInit(). Is it possible?
I would like to use angular's component method, but it seems something is wrong. I have been double checking this code for a while. There is no typo, it seems it fits for the documentation, but, still, it is not working.
I have checked, Angular 1.5.3 is installed.
There is no output on the console. According to the documentation and this blog entry I should see the "onInit" text.
The component's template is displayed correctly, and I can see the the template is loaded, but it seems the controller is not instantiated / fired.
My app is written in Typescript.
The component:
module sayusiando.dilib.spa {
export class LeftHandMenuComponent implements ng.IComponentOptions {
public transclude: boolean = false;
public controller: Function = LeftHandMenuController;
public controllerAs: string = "vm";
public templateUrl: string = "app/layout/leftHandMenu/leftHandMenuTemplate.html";
}
angular
.module("dilib")
.component("dilibLeftHandMenu", new LeftHandMenuComponent());
}
compiled code:
var sayusiando;
(function (sayusiando) {
var dilib;
(function (dilib) {
var spa;
(function (spa) {
var LeftHandMenuComponent = (function () {
function LeftHandMenuComponent() {
this.transclude = false;
this.controller = spa.LeftHandMenuController;
this.controllerAs = "vm";
this.templateUrl = "app/layout/leftHandMenu/leftHandMenuTemplate.html";
}
return LeftHandMenuComponent;
})();
spa.LeftHandMenuComponent = LeftHandMenuComponent;
angular
.module("dilib")
.component("dilibLeftHandMenu", new LeftHandMenuComponent());
})(spa = dilib.spa || (dilib.spa = {}));
})(dilib = sayusiando.dilib || (sayusiando.dilib = {}));
})(sayusiando || (sayusiando = {}));
Layout template:
<div>
<dilib-left-hand-menu class="col-lg-2"></dilib-left-hand-menu>
</div>
LeftHandMenuController:
module sayusiando.dilib.spa {
"use strict";
export interface ILeftHandMenuController {
}
export class LeftHandMenuController implements ILeftHandMenuController {
$onInit: Function = (() => {console.log("onInit");});
static $inject = ["LeftHandMenuService"];
constructor(leftHandMenuService: sayusiando.dilib.spa.ILeftHandMenuService) {
console.log("con");
this.leftHandMenuService = leftHandMenuService;
//this.activate();
console.log("construct");
}
activate() { //activate logic }
}
angular
.module('dilib')
.controller('leftHandMenuController', LeftHandMenuController);
}
Compiled controller code:
var sayusiando;
(function (sayusiando) {
var dilib;
(function (dilib) {
var spa;
(function (spa) {
"use strict";
var LeftHandMenuController = (function () {
function LeftHandMenuController(leftHandMenuService) {
this.$onInit = (function () { console.log("onInit"); });
console.log("con");
this.leftHandMenuService = leftHandMenuService;
//this.activate();
console.log("construct");
}
LeftHandMenuController.prototype.activate = function () {
var _this = this;
this.leftHandMenuService.getLeftHandMenu()
.then(function (result) {
_this.leftHandMenu = result;
});
};
LeftHandMenuController.$inject = ["LeftHandMenuService"];
return LeftHandMenuController;
})();
spa.LeftHandMenuController = LeftHandMenuController;
angular
.module('dilib')
.controller('leftHandMenuController', LeftHandMenuController);
})(spa = dilib.spa || (dilib.spa = {}));
})(dilib = sayusiando.dilib || (sayusiando.dilib = {}));
})(sayusiando || (sayusiando = {}));
I called the $oninit in a wrong way. Here is the proper, well working code:
module sayusiando.dilib.spa {
"use strict";
export interface ILeftHandMenuControllerScope {
}
export class LeftHandMenuController implements ILeftHandMenuControllerScope {
public leftHandMenu: Array<sayusiando.dilib.spa.IModuleContract>;
static $inject = ["leftHandMenuService"];
constructor(
private leftHandMenuService: sayusiando.dilib.spa.ILeftHandMenuService) {
}
public $onInit = () => {
this.leftHandMenuService.getLeftHandMenu()
.then((result: Array<sayusiando.dilib.spa.IModuleContract>): void => {
this.leftHandMenu = result;
});
}
}
angular
.module('dilib')
.controller('leftHandMenuController', LeftHandMenuController);
}
I think this is due to missing dependency parameter list on the module definition. There is a difference in these two statements:
angular.module("dilib")
angular.module("dilib",[])
The first statement tries to access an existing module with name dilib, whereas the second statement tries to create a module dilib with no dependencies. I believe you are trying to create a new module, and hence will need the second format.
Good day,
I have created an object that will manage data access. My app will be using a couple different datastores, so I have created a simple factory to switch between providers:
var dataProvider = {
company: {
getAllCompanies: function (callback) {
var impl = factory.createProvider(implInstance.current)
impl.company.getAllCompanies(callback);
}
}
projects: {
getAllProjects: function (callback) {
var impl = factory.createProvider(implInstance.current)
impl.projects.getAllProjects(callback);
}
}
}
That is all well and good, but I'd rather have my impl variable at the dataProvider level. I'm unsure how I would properly access it though, as 'this' doesn't provide me the right scope when I'm nested so deeply. I'd like something like the following:
var dataProvider = {
impl: function () { return factory.createProvider(implInstance.current) },
company: {
getAllCompanies: function (callback) {
//THIS WON'T WORK
this.impl.company.getAllCompanies(callback);
}
}
Thanks!
You'd want to use the module design pattern for this:
var dataProvider = (function () {
var getImpl = function () {
return factory.createProvider(implInstance.current);
};
return {
company: {
getAllCompanies: function (callback) {
getImpl().company.getAllCompanies(callback);
}
},
projects: {
getAllProjects: function (callback) {
getImpl().projects.getAllProjects(callback);
}
}
}
})();