I want to ask whether there is a way to deploy the angular apps i.e. (modules, controllers, factories) and the bindings so that when users would inspect it or view page source on their browsers they're shown the html and not the bindings like for example {{persons.name}}, {{persons.email}}.
Even when we use ng-bind or ng-bind-template we have our model objects displayed in the code inspection or view page source views of browser.
Understandably the framework it self is based on Java script to start with and the scripts are required on the page, but my question is that is there a way to hide the underlying model architecture in the controller or factories written for some app ?
Can we use some technique for building our scripts and executing them on run time instead while our app initializes and not make code (in our scripts) and bindings (in our html) observable to the users ?
I have done a bit of searching and haven't yet found a suitable solution, most of the articles and references regarding Angular point towards it's core concepts instead.
I have recently started working on Angular so I'm trying to do things the right way as I have a jQuery background.
It sounds like you are wanting to know if you can pre-render angular. While there are some technologies that do this, it is for the sake of search engine optimization, not for end-user use. This is because AngularJS is run client-side. If you have to pre-render it, you completely defeat the purpose of having it (honestly, you should just go with some other technology that does server-side rendering).
If you want to 'hide' your angular code, about all you can do there is minify it with something like uglify. This will make your angular code incredibly difficult to work with, and smaller for the end-user to download. There is an additional 'mangle' capability that uglify offers, but my understanding is that it is difficult or impossible to get it to work with angular due to some of angular's peculiarities regarding dependency injection.
To hide bindings like {{persons.name}} during page loading just add the ng-cloak class to your container (don't forget to add angular css file to your page), Angular will display it when everything is loaded.
You can't, as far as I know, hide your directive in your html code, but honestly I don't think it's really a problem, in front-end development your code is anyway always observable.
Short Answer: No
its not possible to hide the underlying model since Javascript is interpreted at client side it will always be possible to view the underlying model.
However you can also view the interpreted version of your HTML with firebug or any other debugging tool
Related
I've been working with ASP.NET MVC for about a year now. I enjoy the ability to create SPA's especially by using the following tools:
Partial views(via html.action() and renderPartial())
Ajax helpers (Ajax.Actionlink() and Ajax.beginform())
My question is, Is it safe to just continue without a JavaScript frameworks or am i seriously missing out on something by not utilising a Javascript framework like Angular JS.
This depends a lot of the type of application you are building, but in general you don't necessarily have to choose between ASP.NET MVC and Angular, you can use both in a project.
For example, if you have a page with a grid where the user will add rows and you have to calculate sums etc you could use angular on that page (and it will speed up the development process).
But if you have pages with static content you can just serve an html file there using ASP.NET MVC.
And you can even use both of them. For something like a blog post, you can use a static html file for the post content and then implement the comments are with angular.
Since ASP.NET is a server side framework, it can only go that far as AJAX insertions. Angular JS is a client side Framework, designed for SPA in mind. If you are going for a light SPA, ASP.NET will do nicely, but I think you should use the right tools for the right job. Don't hesitate to mix them in order to find the right place between server side rendering and client side dynamism.
You are definitely missing some things.
The purpose of frameworks such as angular is not just to handle your bootstrap tab switches or whatever to display just parts of the UI rather than everything. Sure, you can create small and simple SPAs by utilizing such logic but once you come to create real-world apps that approach will become unusable. The reasons to this are:
Your site will be highly unmaintainable
Frameworks like angular provide much more than just templating (more on that in a moment) but features such as routing, which allows on-demand content loading. That is, instead of sending the whole page to the client, much of which (s)he maybe will not even take a look at, you can load fragments of HTML on-demand, which reduces network usage. Imagine you had to download everything (posts, images, videos, chat messages etc) on Facebook and hide them until you actually want to see them.
Back to templating, this is a very powerful feature. Again, in the case of simple apps you can use custom JS code - that is, concatenate strings to create fragments of HTML and then insert them into the DOM. But even with simple apps this is a smelly thing to do. Imagine you had to write custom JS to concatenate your chat messages in an app like Facebook then insert them into the DOM. With angular2, for example, you can do something like this:
<ul>
<li *ngFor="let msg of messages">{{msg.Sender}} said: {{msg.Content}}</li>
</ul>
This way, Angular2 will do all the parsing and DOM handling for you. That is, you write declarative markup rather than imperative logic for what you want to display.
All in all, they help you to decouple the logic from the UI so you should definitely dig into any of the popular frameworks and get a taste of their capabilities if you want to create rich apps. You will not regret it.
I'm writing a complex, multi-component app using AngularJS. Currently, the main components are ready and I want to improve the performance of the app.
After a short investigation on the field, I found some very useful resources:
11 Tips to Improve AngularJS Performance
Improving AngularJS wep app performance example
AngularJS Performance in large applications
Anyway, I need some additional advises on a few topics:
1. Script and Services/Factories loading
currently, all scripts are loaded at the bottom of the <body></body> tag inside index.html. Therefore, when the user loads directly a ui-route or we simply reload given page, all the scripts are loaded again. I want to load the scripts only in states that use the given script.
Services/Factories/etc. are loaded the same way. This causes pages which do NOT need the given e.g. Service to load it and this is slowing the performance, because of the big data load. I need to initialize/load them only when they are needed in the current state.
2. Translation/Localization
I'm using Angular Translate - i18n Reference, but when I'm translating the page elements I must use e.g. <button>{{btnName | translate}}</button. This technique and the overall usage of filters is pointed as one of the biggest performance drawbacks. The page has a lot of elements so this really might slow the loading. Is there any better solution or any workaround?
3. Overall
I've read the multiple threads on ng-repeat and its track by feature, so I assume it done, but I'm still not 100% sure that I understand the $digest ($apply) cycles correctly.
I read some comments that we should "avoid bind anything directly to a function", but I don't quite get it.
Any additional comments or advises relative to AngularJS and its performance are welcome!
Thank you :)
Reading the above, it looks like you already tried to optimize AngularJS itself. However, there is no mention of optimizations on your build process. I guess it would be wise for you to investigate Grunt or Gulp. With these tools you can concatenate and minify all your JavaScript to a single minified file. This way you only have a one-time payload while initialising your site.
Check this https://medium.com/#dickeyxxx/best-practices-for-building-angular-js-apps-266c1a4a6917
I'm building a multi-page javascript application. I've read a lot into design patterns, and creating applications using a Core/Facade/Module approach w/ loose coupling (pub/sub scribing to events).
I have a pretty good system worked out that minifies & combines all of my module files & related dependencies into a single external javascript file at deployment. Minimizing extra HTTP requests for my application is a design goal -- therefore I'm not too interested in AMD (asynchronous module definition).
I'm using the guidelines delinitated in Nicholas Zakas's presentation,
Scalable JavaScript Application Architecture
http://www.youtube.com/watch?v=vXjVFPosQHw
&&
Addy Osmani's Patterns For Large-Scale JavaScript Application Architecture
http://addyosmani.com/largescalejavascript/
&&
This premium tutorial, by Andrew Burgess from Nettuts, Writing Modular JavaScript
http://marketplace.tutsplus.com/item/writing-modular-javascript/128103/?ref=addyosmani&ref=addyosmani&clickthrough_id=90060087&redirect_back=true
My question is advice on how to go about managing different pages of this application & their associated modules. I'm also using Backbonejs's Router class w/ ballupton's History.js library to manipulate the HTML5 history/state API and dynamically load pages without a refresh while maintaining backwards compatibility for older browsers that don't support the HTML state API. All of my pages share a common code base (single minified & compressed js file).
Here's an outline of the structure I'm thinking of using in my application:
It's essentially a hybrid approach. The top half consists of a Core/Facade/Module pattern with discrete modules that don't interact directly with each other and publish/subscribe to notifications via the facade.
The bottom half consists of my proposed application structure, which notifies a "main controller" when the state/url changes, the main-controller performs any global operations (such as initializing the header & sidebar-menu of my UI if not already initialized) and the instructs the relevant sub-control to run it's init() method (as well as calling destroy(); on any controller that was previously loaded). Each sub-controller (correlates to ex: home-page, calendar-page, reservations-page, etc.) cherry-picks modules from the pool of available modules and initializes them.
Is this a good approach or am I on a bad track? I can see the modules are still independent of each other which is good for scalability.
I've also considered just treating the Router & Controllers as discrete modules and having them publish/subscribe to the Core, and each controller somehow initializes the necessary modules it needs for it's page.
One thing we did to keep history working smoothly was to first change the URL. On change of the URL an event would get triggered, the router would parse the url then figure out what to do. This event would automatically get triggered on page load as well. If you clicked a link it would simply change the URL, which is fairly simple and completely decouples links/buttons from the application logic. This seemed to work well for our application. We used JQM, but we dropped most of their router since we read most of our instructions from some XML file and didn't have a bunch of HTML pages to load into the main viewport area.
I've often seen backbone apps use the router as the core/mediator. This is a good idea. You can simply listen on change events for the URL and then change the page appropriately. This Mediator should probably be a singleton, although singletons are harder to unit test.
The thing I didn't necessarily agree with Backbone on was its definition of "views". The view sort of seems like an action in a controller (well from some perspectives). We added one more level of separation in our application at that point. Our views made ajax requests to template files which were filled in with some JSON and handlebars.js. I'd say your header/sidebar should just be templates. If you need to refresh them then see how you could do extremely simply otherwise you are looking at creating 4 new modules: collection for a list, model for each item, collection view, and model view. I'd couple templates more tightly with some higher level view until they need to be broken down further (eg. some "Application/Main View").
Having this template layer allows you to make superficial changes without recompiling as well, which is nice. Anytime you can put things into "meta" it is a win (well unless it requires you to read XML (ha)). As a bonus you can then cache the template separately as well (or cache bust it separately for that matter).
Your architecture does seem fine though, and is a valid approach to your problem. One tip I'd give is don't over design up front. Iterating is best. You will need to refactor. It is impossible to foresee what would make your application flow more smoothly 3-6 months in advance.
Update on Dec 18th, 2013
Now a days we are using marionette and more addy osmani tricks. On top of the above items we are using AMD's alternate format:
define(function(require) {
var myTemplate = require('hb!mytemplate.handlebars'),
view = require('myview');
...
});
We are also using the marionette application class in combination with wreqr which provides a request/response layer. This allows us to set application wide objects cleanly. It also allows us to define classes without explicitly stating the class name. This is a pretty good way to sandbox. EG:
this.app.setHandler('CanvasClass', function() {
return RaphaelCanvasView;
});
// elsewhere
this.app.request('CanvasClass').text('123', {x:1, y:2});
This all seems to work out pretty well.
You should also checkout aura js and web components. Our directory structure sort of mimics/anticipates those concepts without investing in them yet.
I think it's a good approach.
I've been developing something similar in 2 huge commercial web-apps (minus backbone, and with a custom history manager) and it works great. I'm also not using AMD and all interactions are handled by pub/sub.
One of my best inspirations (which I'm sure you already know) is: https://github.com/aurajs/aura
I'm writing Angular.js application. I want it to be really fast, therefore I serve it completely generated server-side when it is initially loaded. After that every change should be handled client-side by Angular with asynchronous communication with server.
I have ng-view attribute on central <div>. But now Angular regenerates content of this <div> even on first load, before clicking any link. I don't want this behavior because then the server-side generation of page is useless.
How to achieve that?
Although Gloopy's suggestion will work in some cases, it will fail in others (namely ng-repeat). AngularJS does not currently have the ability to render on the server, but this is something that (as far as I know) no other JavaScript framework does either. I also know that server-side rendering is something that the AngularJS developers are looking into, so you may yet see it in the not-too-distant future. :)
When you say you want the application to be "really fast," you should consider where exactly you want this speed. There are a lot of places to consider speed, such as time it takes to bootstrap the app, time it takes to respond, resource intensiveness, etc (you seem to be focusing on bootstrap time). There are often different trade-offs that must be made to balance performance in an application. I'd recommend reading this response to another question on performance with AngularJS for more on the subject: Angular.js Backbone.js or which has better performance
Are you actually running into performance issues, or is this just something you predict to be a problem? If it's the later, I'd recommend building a prototype representative of your type of application to see if it really is an issue. If it's the former and it's taking your app too long to bootstrap on the client side, there may be some optimizations that you can make (for instance, inlining some model data to avoid an additional round trip, or using Gloopy's suggestion). You can also use the profiling tools in Chrome, as well as the AngularJS Batarang to look for slow areas in your application.
btford: You are absolutely right that this sounds like premature optimization - it sounds that way to me either :). Another reason is, that the application should work without JS in very simple way, so this basic layout (and angular does that for me for all other pages), so there will be always rendering on server.
I found a very hacky ugly solution - I bootstrap application after first click on any internal link. After clicking it, I unbind this initial callback, update URL with History.pushState and bootstrap app - it grabs the new URL and regeneration is absolutely OK. Well, I'll keep looking into not-too-distant future :).
I was able to come up with a solution for doing this. It doesn't work perfectly or for everything, but it is ok at least as far as routing and the directive I made that uses ng-repeat.
https://github.com/ithkuil/angular-on-server/wiki/Running-AngularJS-on-the-server-with-Node.js-and-jsdom
We built a web app using jQuery Mobile. It's now nine pages and becoming very unwieldy. jQuery Mobile bundles all "pages" into the same page to simulate the responsiveness of native apps.
We thought about implementing each page as a separate iFrame. The first page contains every iFrame/page and preloads each one. Page transitions happens like JQM by displaying the appropriate page in the viewport. Data is passed between the master page and child pages through iFrame messaging. We think this might be advantageous since:
(1) it won't require additional frameworks;
(2) the web app won't grow beyond 15 pages/iFrames; and
(3) the web app will be accessed through a native app container (i.e., PhoneGap) not a mobile browser.
We're also exploring frameworks. From our research on SO and elsewhere, it seems like Backbone and Spine are two great options for structuring large JavaScript projects.
It's less clear how well they manage JQM projects in particular.
We're looking for three things:
1) What options and frameworks exist for structuring large JQM projects (MVC ideally or worst case, any improvement over a monolithic file)?
2) If you have used Backbone, Spine, or any other JS framework with JQM, please share what you liked/disliked.
3) Do you see any glaring problems with our iFrame architecture, aside from the fact it means building proprietary functionality?
Using iFrames seems to be not optimal especially when lots of different light-weight and easy frameworks exist.
JqueryMobile has it's own router. I didn't like it - using hash tags it requires the page with needed hash was in DOM. Of course, it's possible to load pages dynamically but you'll anyway need to create new pages, add them to page container etc. Such way of working with pages is not suitable for me and also overloads DOM.
Also working with JQM it's possible to use Jquery templates - they allow to store pages or different HTML code, that can be parsed later using passed data. These templates and parsing mechanisms seemed to me very simple and easy to use. But they are not suitable if it's needed to parse complex number of data. Also no support for partials (like in ASP.NET MVC). That means, that you cannot store header and footer in only one file and load them as partials for each page. You'll have to duplicate it for each page.
The rest functional of this framework is great. Lots of controls, theming etc. It seems to be a leader for UI creation - without any doubt. The only thing I didn't like - JQM page transitions.
Now about Backbone. It's a powerful and easy framework to create your app using MVC pattern. Actually, there is no JS framework that allows to create real MVC. But basics are true. Models, Views and Controller (Router). Simple creation of new routes, good documentation and lots of samples on GitHub. Powerful mechanisms to work with views and models - their site will show all the features.
I offer to use Backbone + JQM. But in this case you'll have to disable one of routers to avoid conflicts between these frameworks. Only one should stay.
About paging. There is no need to store all the available pages in DOM. You can create only one JQM page with content element and update it dynamically. Store html in templates, get data from services, parse templates and update content element.
Backbone has a dependency - underscore. At first sight, I didn't want to use Backbone because of this. But underscore is a powerful framework with lots of useful features. And one of them is - templating. Powerful parsing mechanisms for parsing - support loops, js functions, creation of variables in templates etc. Also do not support partials - but you don't need it, because no need to create new page all the time.
When my app had just few pages - I loaded all my js files (frameworks, helpers, service callers, views, models etc.) and stored underscore templates right on my html page. But supporting of such code is a horror. HTML page became huge.
RequireJS framework can solve this problem. It can load not only JS files, but also text templates (using text plugin). All the code in this case will be modular. It's well documented with lots of samples so there is no problem to see how it works.
By the way, the last versions of Backbone officially do not support AMD. But it's still possible to load it using RequireJS.
Also think about scrolling of your content. I won't write a lot about it. Just look at iScroll framework.
So, PhoneGap + Backbone + JQM + RequireJS = Success :)
Go with Sencha Touch, and replace all with it.
15 pages doesn't seem that large to me. I really don't think introducing another framework will make things easier for a site of that scale.
I have felt the same frustrations as you, but instead of putting everything in one giant file, have used ajax page loading to dynamically load pages.
To avoid collisions, I'm just careful to prefix identifiers with the page name. It hasn't been that much of a problem.
It's a little annoying that you have to copy paste the into every file (which makes testing a lot easier, and allows multiple entry points to the site), but I've been able to put up with it.
Despite the drawbacks, splitting pages into HTML files helps with the 'wieldiness', especially if you are inlining the javascript on the page.