LebGeeks

A community for technology geeks in Lebanon.

You are not logged in.

#1 April 2 2018

scorz
Member

SPA Approach

Hello, I am writing an SPA using asp.net(MVC) and I don't want to use a framework (angular/react/whatever) because I don't have time to learn it and I am not that friendly with front-end development.
Anyway, I figured I could create an Object in the main page, and then for each partial view called, I add my elements to the main object (after setting it to null).
I wrote my script inside the html file, I could of course write the scripts on an external .js but the file will remain on the browser's memory.

What are the cons of this approach?

<script>
//main var
mainObj = {}
</script>
//Script Inside the page
<script>
$(function(){
mainObj = null
mainObj.foo = "foo"
mainObj.bar = function(){}
})
</script>

Offline

#2 April 2 2018

rolf
Member

Re: SPA Approach

Main con of putting your script in the HTML is that it will be loaded every time. Normally the javascript is shared across the site, so the JS file is loaded once and then kept in cache. If you put all your javascript in one file then it gets loaded once and then it is kept in the cache. Subsequent pages will load faster.

It is OK to have a few lines inside your HTML if they are specific to that particular page.

However, since you are writing an SPA (I just realized) then you only have one HTML page to load (normally) therefore what I said don't really apply. The only thing is that if you put your script in an external file then you can do things such as deferred or asynchronous loading so that the page loads faster.

Also if you are building your JS then it's obviously easier to have it in an external file (but you're not!).

I'm assuming your script will be in the header or at the end of the BODY. If you sprinkle SCRIPT tags across the document, then it will be disorganized and harder to keep track of what is happening and to edit the code, in my opinion.

If you are in a hurry then just get something done and then you can worry about such optimization! Why are you being concerned with that?

I'm not sure what you're trying to do with that object.

I know that you're in a hurry, but please, do

'use strict';

And then declare your object with 'var'.
No offense, I hate to look at javascript from the last decade!

Last edited by rolf (April 2 2018)

Offline

#3 April 3 2018

scorz
Member

Re: SPA Approach

If you are in a hurry then just get something done and then you can worry about such optimization!
Why are you being concerned with that?

Well because I want my design to be right, I hate redoing all the work.

I'm not sure what you're trying to do with that object.

And then declare your object with 'var'.

I have a layout page, where I've referenced a "main.js"
Inside this file, there's the mainObj object (I didn't user 'var' to make it a global variable - but i guess i don't need it)
Whenever a user load a page, on document ready of that page, I delete all the element of the mainObj ( mainObj  = null ).
And then I re-create the object (mainObj  = {}) and insert the elements of the page in it.

e.g:

$(function(){
mainObj  = null
mainObj  = {}
mainObj.randomFunc = function(){ alert("I Sucks at javascript")}
mainOb.randomVar = "Hello world"
})

I finally access the function/variables needed for the page(partial view) by calling mainObj.randomFunc()

Offline

#4 April 3 2018

rolf
Member

Re: SPA Approach

scorz wrote:

If you are in a hurry then just get something done and then you can worry about such optimization!
Why are you being concerned with that?

Well because I want my design to be right, I hate redoing all the work.

Fair enough!

My philosophy is to do something fast then see where it is having problems, and iterate over it. There is no such things as absolutely right design, it depends on what you are trying to do. Most often the problems will appear once you are at a more advanced stage of the design.
This might be what is called "premature optimization" and to be honest I often fall into that.

There is also something called the "second system syndrome" which is when you do something quick and dirty and it works, but then you want to create it again and this time want it to be perfect, use advanced features, be performant, etc. and you never get it done because you're so busy making it perfect.


scorz wrote:

I'm not sure what you're trying to do with that object.

And then declare your object with 'var'.

I have a layout page, where I've referenced a "main.js"
Inside this file, there's the mainObj object (I didn't user 'var' to make it a global variable - but i guess i don't need it)
Whenever a user load a page, on document ready of that page, I delete all the element of the mainObj ( mainObj  = null ).
And then I re-create the object (mainObj  = {}) and insert the elements of the page in it.

e.g:

$(function(){
mainObj  = null
mainObj  = {}
mainObj.randomFunc = function(){ alert("I Sucks at javascript")}
mainOb.randomVar = "Hello world"
})

I finally access the function/variables needed for the page(partial view) by calling mainObj.randomFunc()

OK, but I'm still confused. document.ready fires only once when you load the page. If it is firing again, it means that you are reloading the page, in which case, you are not developing an SPA. Also, any javascript variable assignement will be lost when you reload the page.

What are you trying to achieve, or which problem are you trying to resolve with this code?

Regarding non-strict javascript, it's usually considered bad practice and I personally don't like it. I used to code like this when I started and it was still common back then. Anyway if you replace mainObj by window.mainObj then your code will work in strict mode.

Last edited by rolf (April 3 2018)

Offline

#5 April 3 2018

scorz
Member

Re: SPA Approach

here is no such things as absolutely right design, it depends on what you are trying to do.

I totally agree! But my main problem is that I've never designed by myself front-end so I am afraid it will be a mess.

OK, but I'm still confused. document.ready fires only once when you load the page. If it is firing again, it means that you are reloading the page, in which case, you are not developing an SPA. Also, any javascript variable assignement will be lost when you reload the page.

I am not reloading pages, I am just loading Partial View inside a main View(using ajax). So the variable of the main View remain there including my mainObj.

What are you trying to achieve, or which problem are you trying to resolve with this code?

I don't want the script of PartialView0 to remain in the browser when I load PartialView1,
I figured if I used a global object to store my variables there, I can overwrite it when I render PartialView1.
I've changed the way of overwriting, instead of document ready I am doing it before navigation

I am using this function to navigate through Partial views:

function loadLMS(url) {
    $.ajax({
        url: url,
        cache: false,
        success: function (result) {
            ClearObject()
            $("#LMSContainer").html(result)
        },
        error: function (result) { }
    })
}

and ClearObject() is:

function ClearObject() {
    mainObj = new Object()
}

Inside my PartialViews I have

<script>
mainObj.Whatever....
</script>

It may be the worst approach ever and maybe I am missing the whole point of SPA design.

Offline

#6 April 4 2018

rolf
Member

Re: SPA Approach

Document.ready is only triggered once by page load!

Thank you for your explanation, I have a much better idea of what you're trying to do.

If you still want to go down the object-oriented way, I suggests having a global "View" object and not overwriting it it, but calling a setter method on that object.

For example:

function View() {
  this.state = {}
  // the constructor goes here
}

View.prototype.setState = function(newState) {
   this.state = newState;
}

To use it:

window.mainView = new View();

Then when you load a new partial view, you can do:

window.mainView.setState({
  title: "blah",
  content: "Lorem Ipsum..."
}) 

To read the state:

window.mainView.state
window.mainView.state.title
...

This will make your "global variable" a little more manageable, for example if the state is being overwritten and you don't know from where, the you can modify setState and find out from where it is being overwritten. You can also trigger an event when the state is being changed/overwritten, which I think will be useful, and you will want to refresh/do some things on the page following the state being changed.

Now that you have only 1 global object it's OK and easy to keep track of it. But if and when you have more, then it is better to organize your code into objects and methods which deal with the object itself, rather than to have functions write directly to global objects.

If prototypal Javascript is intimidating, you can just do:

window.mainView = {
   state: {},
   setState: setState = function(newState) {
      // wait... we can't use "this" here, it won't be bound correctly
      window.mainView.state = newState;
   }
}

If your code gets more complicated, then you can extend this into the MVC pattern (Model, View, Controller) which is just a way of organizing and conceptualizing things. You'd have a Model object for working with data, a View object for dealing with the... view, and a Controller object for controlling and synchronizing all the other objects.

This approach also goes a little in the direction of React, but React does much more then that.

I hope your SPA will go well! I'm happy to help in the future.

Last edited by rolf (April 4 2018)

Offline

#7 April 4 2018

scorz
Member

Re: SPA Approach

Thanks for your time!
I'll apply your suggested way of object-oriented, I'd go with prototypal(It feels more oo)
I am already using asp.net mvc so I might as well use this design pattern for javascript.
I am not sure if it's a good idea, but I can separate logically the model/view/control stuff in the window.mainView

Something like

window.mainView.setState({
  model: {},
  view: {},
  control: {}
})

Offline

#8 April 4 2018

rolf
Member

Re: SPA Approach

Hmm "mainView" is supposed to be a view object so it should not handle control and other stuff IMHO. Anyway it's a little early, just nice to foresee a path for if (or when?) your app becomes more complex.

You're welcome, I am happy to discuss these! My pleasure.

I think that Object oriented makes the code easier to organise and to understand. I have also worked on a project once where everything was an object encapsulated into another object. Although it did keep the code organized, it was a lot of work to figure out how to pass information around between objects. So I guess too much OO can also happen.

In the end it's a learning experience, hopefully it will be a good one for you.

Last edited by rolf (April 4 2018)

Offline

#9 April 4 2018

scorz
Member

Re: SPA Approach

Hmm "mainView" is supposed to be a view object so it should not handle control and other stuff IMHO. Anyway it's a little early, just nice to foresee a path for if (or when?) your app becomes more complex.

Yeah i know, the snippet was if it became more complex later and for keeping a unique global variable. It was my bad not renaming window.mainView!

I think that Object oriented makes the code easier to organise and to understand. I have also worked on a project once where everything was an object encapsulated into another object. Although it did keep the code organized, it was a lot of work to figure out how to pass information around between objects. So I guess too much OO can also happen.

OOP and especially C++ are effected with the second system syndrome.
Like you've mentioned it can get too complex.
I've coded OOP in Java/C++/C#, and in my personal experience C# was the smoothest.
Applying design pattern(repository, observable, strategy, dependency injection...) is quite simple.

Offline

Board footer