Calling javaScript function by a JavaScript class - javascript

I am a newbie in the ASP.NET technology and also I did not find any answer on the forum (however if there is one please let me know)
I am writing ASP.NET MVC app and I use a lot of Ajax there.
At the moment I am rewriting "free" Javascript into classes and their methods, so the code will be more readable.
And here is the problem:
For such a case:
#Ajax.ActionLink("Text", "SomeAction", "Controller", new AjaxOptions() { UpdateTargetId="content", HttpMethod="Post", OnComplete="javascriptActionStatedBelow"})
<script>
function javascriptActionStatedBelow()
{
// do stuff here
}
</script>
Everyting works perfectly fine. However when I try to input the function into the class and then call it, it does not work.
I am doing this in the following way:
<script>
// is in seperate file and here is added reference to it
class myClass {
javascriptActionStatedBelow() {
// do stuff here
}
}
// this is on the view page
var someObj = new myClass();
</script>
I initilize the object in the header and then in the body I put the following.
#Ajax.ActionLink("Text", "SomeAction", "Controller", new AjaxOptions() { UpdateTargetId="content", HttpMethod="Post", OnComplete= "someObj.javascriptActionStatedBelow" })
The second idea does not work.
What am I doing wrong ? Is there a better solution for managing javascript content in ASP.NET MVC applications while using AJAX ?
I know about $.ajax type of solution but actions like OnComplete, OnBegin,.. etc worked perfectly for now.

It's important to note that there are no classes in JavaScript. Functions can be used to somewhat simulate classes, but in general JavaScript is a class-less language. However from ECMAScript 2015, classes are introduced which are primarily syntactical sugar over JavaScript's existing prototype-based inheritance. For your requirement, should defined the java script function as IIFE. If your javascript is not targeted for ECMAScript 2015, then you can write the code as follows for IIFE:
Define the IIFE method as
var myClass = (function () {
// Object that's returned from the IIFE.
return {
javascriptActionStatedBelow: function() {
}
};
}());
Now in view's script section you can use it as
// this is on the view page
var someObj = myClass.javascriptActionStatedBelow();

Javascript isn’t strictly a “class-based” object-oriented language, hence the same patterns that apply to conventional back-end object-oriented languages don’t apply there effectively. However, there is a number of ways to make javascript much more convenient and manageable.
One of the ways that I highly recommend is through the use of “Module / Revealing module pattern”, or simply put through making javascript “namespaces” and calling them wherever needed. This reduces the clutter in View files and mimics the design we are used to seeing.
In a separate js file (conventionally named similar to the view file), you will define your javascript as follows:
var className = (function() {
// private variables and functions
var javacriptField1 = "some field";
var javascriptFunction1 = function() {
//function logic
}
var javascriptFunction2 = function() {
//function logic
}
// public API
return {
javascriptField1 : javascriptField1,
javascriptFunction1: javascriptFunction1,
javascriptFunction2: javascriptFunction2
};
})();
In your view you would include your js file:
<script src="~/Scripts/myfile.js"></script>
And use it within the javascript on your view as follows:
var obj = className.javascriptFunction1();
Following is a very nice tutorial you should go through:
https://www.dcaric.com/blog/asp-net-mvc-and-revealing-module-pattern
Here’s another example:
How to use javascript namespaces correctly in a View / PartialView

Related

How to modularize a javascript function which uses constructor.prototype?

Modularization
I am working on a simple javascript library which works like jQuery, but I want to add more features to it.
The code is starting to get big (~300 lines) and I want to modularize it. The basic structure is this:
var $ = function(){
constructor = function(selector){
//query selector all the elements with selector
}
var instantiate = function(selector){
return new constructor(selector)
}
return instantiate;
}()
And features work like this:
constructor.prototype.someFunction = function(){
//do something
}
So, I wonder: what is the best way to modularize it? Do I just create separated files with functions and then call it in constructor.prototype? Do I import this function and modify it in other files?
I do not mind changing the whole code if it is necessary or makes a good improvement.

How do I call upon my settings (array) listed in html using prototype in my javascript file?

I'm relatively new to javascript development and have tried to construct my own framework. I've been trying to convert my standard javascript functions to a framework. However I've been stuck at a relatively simple (I think), but nowhere explained issue.
In my HTML I call on the settings I want to use in my JavaScript (the user has to be able to edit them in html, not in js as it will be minified).
<script>
$(document).ready(function(){
var settings = {authenticFilter: 'on',
randomizeHeaders: {state: 'on', topHeader: 'h1', bottomHeader: 'h2'},
};
var papery = new Papery(settings);
});
</script>
But I can't seem to figure out how to use the settings I have given to my framework in the javascript file.
I know I can call upon this.settings = settings; in my javascript file, but in an if statement below, I want make use of specific settings in the given settings. However this option and several other ways I've tried to use the settings won't work. Can I even use the settings I give to the prototype from my html in an array?
var Papery = function (settings) {
Papery.authenticFilter = function() {
if (Papery.authenticFilter == 'on'){
$("img").addClass("authenticFilter");
$(".authenticFilter").css({"filter": "sepia(80%) grayscale(1) contrast(1) opacity(0.7)", "-webkit-filter": "sepia(80%) contrast(1) opacity(0.7)"});
}
}
}
You are using Papery.authenticFilter instead of settings.authenticFilter. Keep in mind that in usual libraries, a bunch of default settings are set in initialization in case they are not defined on the settings passed on the constructor.

Using Meteor and javascript in an object oriented style

Please bear with me as I'm new to JS and am having trouble implementing some things with Meteor. I implemented a class in JavaScript using
function Class() {
this.property = 0
this.method = function () {
return "method called"
}
}
I made a new Meteor Collection bu using new Meteor.collection and successfully retrieved the data on the client and can display Class.property in the html template. However, I am unable to access Class.method and was wondering if there's any way to make this happen and if using Meteor.methods to define functions that take the Class instance as input is the best way to go.
For anyone still looking at this, the reason the code doesn't work is because mongodb stores documents as bson. bson, just like json, does not support functions (http://bsonspec.org) so when the above class is saved by meteor into mongo, the method is not saved as part of the document.
There is no easy elegant solution I'm aware of. I have the same issue. In order to utilise the class method you would need to instantiate the class each time you needed it, which you could implement as part of a database model.
This is not really an answer but in meteor's package manager you can add libraries like backbone.js which gives you models, collection and views and a nice router which I find very handy when making meteor apps. Backbone works well with jQuery.
My other suggestion is using a library like Mootools which unlike jQuery doesn't try to change the way you write javascript but enhancing the experience of making object oriented javascript. (see: jqueryvsmootools). With mootools you can can make a class the following way...
var MyClass = new Class({
'Implements': [Options],
//default options
'options': {
'foo': null
},
'initialize': function(options) {
this.foo = options.foo;
},
'bar' : function() {
return this.foo;
}
});
var blub = new MyClass({'foo': 'Hello World'});
blub.bar(); // "Hello World"
I was looking to do the same thing.
I found a function called "transform" that is called when getting something from a meteor collection. You can use it to add a function to a meteor object just as you require.
Here is an example of adding an "endDate" function and "remaining" functions to a meteor object
Products = new Meteor.Collection("Products", {
transform: function (doc) {
doc.endDate = function () {
// SugarJS gives us minutesAfter() which gives us a nice syntax for
// creating new Date objects
// http://sugarjs.com/api/Number/unitAfter
return ((25).minutesAfter(this.startDate));
};
doc.remaining = function () {
return this.endDate().getTime() - Date.now();
};
return doc;
}
});
Read more here:
http://www.okgrow.com/posts/2014/05/19/meteor-transform/
This approach worked beautifully for me:
http://www.okgrow.com/posts/2014/05/19/meteor-transform/
I don't know anything about Meteor, but I see a problem with your code. You're missing a semi-colon after:
this.property = 0
Without that semi-colon, the javascript interpreter will not execute the this.method assignment.

simple Constructor Pattern

I have worked with oop style scripting before and trying to get some kind of system with javascript. I wanted to try the most basic pattern, Constructor Pattern.
So I setup one js file called ImageView with a constructor matching the name of the js file.
function ImageView(){
alert( 'this is working');
}
Then I set up another js file called Main.js which will be the main instantiation class.
$(document).ready(function(){
var imageViewer = new ImageView();
//ImageView();
});
Now what I don't get is I can call this object ImageView without even the new constructor call. For example ImageView(). From what I gather this is just another global function and not a encapsulated class. I'm trying to get away from global crap and separate my methods and properties to their own class. What am I missing her.
Others have already answered what the difference is between using new and not using it, so I'll answer your entirely separate question: how do I avoid globals in JS?
The answer is that you can't entirely. You will always have at least one, in which you can stuff your other stuff. So for example if you wanted a "namespace" of xyz, you would do:
// global:
var xyz = {}; // or, window.xyz = {} if you are in a browser and want to be more explicit.
// "encapsulated" within the xyz "namespace":
xyz.ImageView = function () { alert("This is working"); };
There is a better solution: use the emerging concept of JavaScript modules. These are not language features (at least not in the current version of JavaScript), so they are really just hacks introduced by very clever libraries that overwrite a couple of global variables to let you avoid creating any more than the ones provided by those libraries. A good example is RequireJS, where you could do something like the following:
// In xyz.js, define the xyz module (name automatically derived from filename).
// Whatever is returned from the function you pass to define is "the xyz module"
define(function () {
return {
ImageView: function () { alert("This is working"); }
};
});
// In other code, in a different file, you can say "I require the xyz module
// to do my work," and pass require a function saying "once you've got the xyz module
// for me, here's the work I will do with it".
require(["xyz"], function (xyz) { // dependency array maps to callback arguments
// I got the xyz module, including the ImageView function it exported. Use it!
var imageViewer = new xyz.ImageView();
});
Here the clever globals RequireJS introduces are the functions define and require, but if you use them right, you can avoid ever introducing any further globals beside those two.
Inside of ImageView, the value of this will be different if you call it with new. Without, it's just another function. With new it will create a new ImageView instance and bind it to the variable this.
First off JavaScript doesn't have built in namespaces. It can only be simulated. You must also include each javascript file you plan on using.
Your right about just calling ImageView() that basically invokes the constructor on this which is next level of scope.
Using new ImageView() creates a new Object of constructor ImageView and this points to the new instance.
JavaScript is a prototype language with loose typing.

Programming OOP in Javascript - Properly

I'm interesting in improving my javascript code to be properly OOP.... currently I tend to do something like this:
jQuery(document).ready(function () {
Page.form = (function () {
return {
//generate a new PDF
generatePDF: function () {
},
//Update the list of PDFs available for download
updatePDFDownloads: function () {
},
/*
* Field specific functionality
*/
field: (function () {
return {
//show the edit prompt
edit: function (id, name) {
},
//refresh the value of a field with the latest from the database
refresh: function (id) {
}
};
}())
};
}());
});
In the end it's just mainly organized functions I suppose... what's a good resource where I can learn to program javascript in an OOP manner, or what suggestions would you have for improving my current style of programming?
It seems like I should do a sort of model prototype and have my form object inherit from that prototype.
(I'm using jQuery instead of $ because of conflicts with prototypeJS)
Your question is quite broad so I don't think a complete answer is possible here. But here are a few points.
Regarding the code you have shown. You're jumping a couple of redundant hoops.
Unless you're accessing the DOM in some way, there is no need to wrap your code in jQuery(document).ready()
There is no need to return an object from a self calling anonymous function unless you're closing over some private functions or data
The object you have created can be created more simply (a good thing) like this
var Page = {
form: {
//generate a new PDF
generatePDF: function () {
},
//Update the list of PDFs available for download
updatePDFDownloads: function () {
},
/*
* Field specific functionality
*/
field: {
//show the edit prompt
edit: function (id, name) {
},
//refresh the value of a field with the latest from the database
refresh: function (id) {
}
}
}
};
It's easier to read and less confusing, only do things that buy you something. see cargo cult programming
Here's an example using a self calling anonymous function to create private members
var Obj = (function() {
privateFunction( param ) {
// do something with param
}
var privateVar = 10;
return {
// publicMethod has access to privateFunction and privateVar
publicMethod: function() {
return privateFunction( privateVar );
}
}
})();
The structure you have used, object literals are very good, as you say, at grouping a set of functions (methods) and properties. This is a kind of namespace. It is also a way of creating a Singleton. You may also want to create many objects of the same Class.
JavaScript doesn't have classes like traditional OO languages (I'll get to that) but at the simplest level it's very easy to create a 'template' for creating objects of a particular type. These 'templates' are normal functions called constructors.
// a constructor
// it creates a drink with a particular thirst quenchingness
function Drink( quenchingness ) {
this.quenchingness = quenchingness;
}
// all drinks created with the Drink constructor get the chill method
// which works on their own particular quenchingness
Drink.prototype.chill = function() {
this.quenchingness *= 2; //twice as thirst quenching
}
var orange = new Drink( 10 );
var beer = new Drink( 125 );
var i_will_have = ( orange.quenchingness > beer.quenchingness )
? orange
: beer; //beer
var beer2 = new Drink( 125 );
beer2.chill();
var i_will_have = ( beer2.quenchingness > beer.quenchingness )
? beer2
: beer; //beer2 - it's been chilled!
There's a lot to know about constructors. You'll have to search around. There are lots of examples on SO.
Inheritance, the foundation of OO, is not that intuitive in js because it is prototypal. I won't go into that here because you will more than likely not use js's native prototypal inheritance paradigm directly.
This is because there are libraries that mimic classical inheritance very effectively, Prototype (inheritance) or mootools (Class) for example. There are others.
Many say that inheritance is overused in OO and that you should favour composition and this brings me to what I initially set out to recommend when I started this rambling answer.
Design patterns in JavaScript are as useful as in any OO language and you should familiarise yourself with them
I recommend you read Pro JavaScript Design Patterns.
There, that's it
Some good sources for Object-Oriented JavaScript and JavaScript in general...
Online Articles
How to "properly" create a custom object in JavaScript?
https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript
http://mckoss.com/jscript/object.htm
http://ejohn.org/blog/simple-javascript-inheritance/
JavaScript: How To Get Private, Privileged, Public And Static Members (Properties And Methods)
Books
JavaScript: The Good Parts - Douglas Crockford
Object-Oriented JavaScript - Stoyan Stefanov
I hope this helps.
Hristo
There isn't one correct way... Some people use a framework to define their object, I like to just extend prototype directly. Anyhow, I wanted to say that Oran Looney has some good posts on OO mechanics in JS:
http://oranlooney.com/classes-and-objects-javascript/
Its also worth looking at his other articles:
http://oranlooney.com/deep-copy-javascript/
http://oranlooney.com/functional-javascript/
The top 3 I suggest to read is
JavaScript and Object Oriented Programming (OOP)
Classical Inheritance in JavaScript
Prototypal Inheritance in JavaScript
Have a nice reading!
The code we are using follows this basic structure:
//Create and define Global NameSpace Object
( function(GlobalObject, $, undefined)
{
GlobalObject.Method = function()
{
///<summary></summary>
}
}) (GlobalObject = GlobalObject || {}, jQuery);
//New object for specific functionality
( function(Functionality.Events, $, undefined)
{
//Member Variables
var Variable; // (Used for) , (type)
// Initialize
GlobalObject.Functionality.Events.Init = function()
{
///<summary></summary>
}
// public method
this.PublicMethod = function(oParam)
{
///<summary></summary>
///<param type=""></param>
}
// protected method (typically define in global object, but can be made available from here)
GlobalObject.Functionality.ProtectedMethod = function()
{
///<summary></summary>
}
// internal method (typically define in global object, but can be made available from here)
GlobalObject.InternalMethod = function()
{
///<summary></summary>
}
// private method
var privateMethod = function()
{
///<summary></summary>
}
}) (GlobalObject.Funcitonality.Events = GlobalObject.Funcitonality.Events || {}, jQuery )
The strength to this is that it initializes the Global object automatically, allows you to maintain the intergrity of your code, and organizes each piece of functionality into a specific grouping by your definition. This structure is solid, presenting all of the basic syntactical things you would expect from OOP without the key words. Even setting up intelisense is possible with javascript, and then defining each peice and referencing them makes writing javascript cleaner and more manageable. Hope this layout helps!
I dont think it matters what language you use, good OOP is good OOP. I like to split up my concerns as much as possible by using an MVC architecture. Since JavaScript is very event based, I also use the observer design pattern mostly.
Heres a tutorial you can read about MVC using jQuery.

Categories