Thinking in Angular Way - javascript

I am working on project with more than 1500 HTML pages.
This project was previously implemented in jQuery and JS code. Now I have to revamp this SPA using AngularJS.
I have gone through basics of angularjs. We have several interaction on in our projects (Moving from one page to another).
Is <head ngapp="routingApp"> is the right place to configure the routing for whole project or can I define it separately for each module?
As the project also uses jQuery for bootstrap dependency does it make any sense just to include jQuery for bootstrap?

I would strongly discourage you from declaring all your routing in one file. It will lead to really big file & bad maintainability.
If you have such a big project I'll advise you to read the Google's recommendation for AngularJS structure first.
Then every developer will have a way to 'scope' his work within one module & it would be easier for him to understand it.
Moreover it would be much easier to disable/enable some modules just by excluding them from final composing&"compilation" phase.
E.g. you'll have a module that defines routes that can be reached within this module.
I strongly recommend using Gulp & Bower (you'll have to have Node.js) to manage you dependency management as well as composition/compilation phase management.
As a teaser here you have gulp scripts compilation for fractal structure:
gulp.task('scripts', function () {
var depJS = dependencies.bower.js.map(function (dep) { return config.bowerLib + dep; });
depJS = depJS.concat(dependencies.node.js.map(function (dep) { return config.nodeLib + dep; }));
var srcJS = ['app/modules/app.js', 'app/modules/**/*.module.js', 'app/modules/**/*.js'];
var libPipe = gulp.src(depJS)
.pipe(plumber())
.pipe(concat('lib.min.js'))
.pipe(size({title: 'js-before lib'}))
.pipe(gulpif(config.minimize.perform, uglify(config.minimize.js)))
.pipe(size({title: ' js-after lib'}))
.pipe(gulp.dest(config.scriptsOutDir));
var pipe = gulp.src(srcJS)
.pipe(plumber())
.pipe(concat('all.min.js'))
.pipe(size({title: 'js-before all'}))
.pipe(gulpif(config.minimize.perform, uglify(config.minimize.js)))
.pipe(size({title: ' js-after all'}))
.pipe(gulp.dest(config.scriptsOutDir));
});
The second question - AngularJS have jQLite inside it. When the jQuery is available the jQuery implementation is used. (side note: use jQuery/jqlite only in directives). It depends how vastly the jQuery library is used throughout your project & what methods are used. Can it be replaced by jqlite (limited jQuery) or can you just rewrite all jquery specific DOM/etc. manipulation by directives.
You've mentioned bootstrap - did you mean Twitter Bootstrap? If so, look at the AngularJS UI-Bootstrap

You can definetaly separate it in modules, look at https://github.com/angular-ui/ui-router.
1.) If you are asking if its right to define whole routing inside 1 index.html and one angular app , yes it is right place. It is purpose of SPA

Related

How to properly import js files in meteor

I like keeping my javascript files as small as possible and using an architectural pattern. This usually means splitting my js files in Services, Controllers, Models, Views, etc.
Meteor automatically loads all js files. However every variable defined in any js file is processed as a local variable for that file. To be able to access them I have to define them like so:
//global
my_global_function = function(){
}
//not global
var my_global_function = function(){
}
//not global
function my_global_function(){
}
Defining a variable/function without the keyword var or function is not good practice. What are the possible alternatives?
The best option is to use ES2015 modules.
Meteor does not support modules natively yet, but there are packages that bring this support.
For example, universe:modules.
With modules you can import and export some variables/functions/classes/etc:
// module1.import.js
import alertSomething from './module2'
Meteor.startup(() => {
alertSomething();
});
// module2.import.js
export default function alertSomething() {
alert('something');
}
universe:modules is not the only solution, there are other similar projects. I love this one specially https://github.com/thereactivestack/kickstart-simple. It replaces Meteor's build system with WebPack's and enables hot-reloading if you use React.
UPDATE:
Meteor does support ES6 modules now
Since you seem very interested in proper architectural design, I would recommend looking at Meteor packages. Essentially, you have to declare any globally exposed variable in the package.js configuration, which is what you want: as little "leakage" as possible. Within a package, you can afford to be a little bit more sloppy, but you can still use var (and the absence of var) for more fine-grained control within a package. This can be done within Meteor right now.
You can find most information in the package documentation. The easiest way to get started is to create a package using meteor create --package [package-name]. This sets up a basic structure to play with. The api.export function is what controls exposed variables. See doc here.
Additionally, be careful with adding an unnecessary layer on top of the intrinsic Meteor architectural design. Templates are views, server side methods are services, etc. There are only some things that you don't get out of the box, so usually you'll add something like Astronomy or SimpleSchema.
Adding too much of your own architecture is probably going to end with you fighting the Meteor framework itself...

Keeping angularjs decoupled from an application

I'm planning out an application that ideally I'd like to keep decoupled from Angular, so all the dom interaction will go into an Angular layer but the core business logic will be kept in a standalone app that is totally unaware of Angular. The two will communicate via Angular services that are able to send messages to the core application.
The standalone app will most likely use requirejs to handle dependency injection.
What I'm unsure of is how to get a module that may be declared something like this:
define('AppInteractor', ['require'], function(requre){
// Set up interactor functionality
});
Into an Angular service.
My first though was to have some kind of adapter like this:
define(['AppInteractor', 'angular'], function(interactor, angular) {
var app = angular.module('appInteractor', []).service('AppInteractor', interactor);
});
This would register the AppInteractor as a service within an angular module, the problem with this approach seems to be that because requirejs loads things asynchronously the service hasn't been set when the angular code runs. It also seems to end up with angular loading twice which presumably also doesn't help matters.
I've seen a few articles covering loading all Angular components via require but I was hoping there might be simpler way to make this work.
Can anyone recommend how I might make this work?
If you are going to add a service after the main modules initialization, I recommend you add it to your application module
define(['AppInteractor', 'angular'], function(interactor, angular) {
// There is no second parameter, because we are getting an existing
// module, not creating a new one.
var app = angular.module('appModule');
app.service('AppInteractor', interactor);
});
Otherwise, if you want to group all your other logic in a different module, you will need to import the module and add it as a requirement of your application module.
define(['AppInteractorModule', 'angular'], function(interactorModule, angular) {
var app = angular.module('appModule', [interactorModule.name]);
});
I also recommend you use a tool like ES6 (6to5, traceur), browserify or Typescript for your module management, and then compile to AMD. I find it easier and cleaner for development.

Best way to work with angularJS and jquery's $('document').ready()

I have a bunch of pages given to me by a designer that has to be integrated with my existing project in AngularJS.
The page that I have been given uses a lot of jquery . The one thing that is causing problems is the jquery's $('document').ready() function.
Since in an angular project the page is just loaded once, most of the document.ready() parts in any of the pages are not working. Every time a page changes, there is some code to inside this function that doesn't work.
So whichever controller in my project is supposed to have any code that work's on document.ready I am throwing it in the controller like this :
setTimeout(function(){
$scope.$apply(function() {
var _wht=($(window).height());
var _wwt=($(window).width());
_wht=($(window).height());
_wwt=($(window).width());
if(_wht > 450){
var mcht = _wht - ($('header').height()+ $('footer').height()+50);
$('.login-page').css('height',mcht+'px');
$('.login-page').css('padding-top',((mcht - 158)/2) +'px');
}
});
});
This works very well.
But I think this counters angularJS' philosophy of separation of concerns . The controller is where you have only your business logic.
Where is the best place to throw this piece of code ?
AngularJS is here to be built for robust arhitecture and that is why we see so many modules in terms of directives and other components. Putting JQuery with it will be like going away from their core design and you will yourself end up in a mess maintaining the codebase.
jQuery is a crutch if you are writing AngularJS applications.
If you’re starting an AngularJS app, take a good look at ng-boilerplate. Then take a look at ui-bootstrap’s directives. They are a living example of how you can do “jQuery things” with a fraction of the code, and build an app that is easier to maintain, way more testable, and generally nicer to work with.
Take a look at this stuff
How do I “think in AngularJS” if I have a jQuery background? - An excellent Stack Overflow post that expands on this viewpoint
Using AngularJS? Then stop using jQuery
Instead of $('document').ready() you can also use.
angular.element(document).ready(function() {
:
:
});

AngularJs Load dependencies files

I'm learning AngularJS and in all tutorials and screencasts I always saw to use angular writing code all in a unique file, example directives, controllers, factories etc...
Logically for large applications, you will split out the code, make it maintainable and flexible in multiple files and also we should be careful about how many <script> tags we have to require to let our JavaScript files run correctly.
I would like to know which is the best practice to require files when needed, importing less javascript files possible in my view. I took a look at RequireJs but it seems a bit complicated to use it. Is there some tool more efficient and easy to use? Or any good resource to get started?
A small example can be that I have a sort of plugin that has been built using directives, controllers and factories:
app-|
--Controllers
|_ pluginController.js
--Directives
|_ pluginDirective.js
--Factories
|_ pluginFactory.js
Instead of requiring all three files how do you make it work?
Here' a great example of how to use RequireJS and AngularJS together. It's a fork of the Angular Seed project and it should hopefully point you in the right direction. It comes with RequireJS baked right in. I definitely recommend learning RequireJS!
I would advice you to read up on dependency injection in the Angular documentaion. It all depends on how you set things up to be honest. If you want to use your service/factory in your controller then you would add the factory as a dependency in your controller or directive. See example below :
Angular.module('{YOUR MODULE NAME}').controller('{YOUR CONTORLLER NAME}', ['$scope', '{FACTORY NAME}',
function($scope,{FACTORY NAME}) {
}]
To invoke the directive within your controller, you would simply could simple add the directive to your controller template. This is a basic example, to learn more read about dependancy injectioninvoke
To be clear that I understand - e.g. I want to use "angularFileUpload" module, I need to add it to my module dependency list -
angular
.module('kids', ['angularFileUpload'
])
and load the script?
<script src="angularjs/plugins/angular-file-upload/angular-file-upload.min.js" type="text/javascript"></script>
Thanks for help.

Injecting additional mvc logic into ext js app

I'm new to ext js, but went through the getting started guide and have managed to create my own app.
Now I'm building a plugin for an e-commerce system (shopware) and need to dynamically extend an app.
I've managed to add a view by monkey patching an existing controller:
//{extends file="[default]backend/article/controller/main.js"}
//{namespace name=backend/article/view/main}
//{block name="backend/article/controller/main" append}
Ext.define('Shopware.apps.Article.controller.MyApp', {
override: 'Shopware.apps.Article.controller.Main',
openMainWindow: function() {
var me = this,
mainwindow = me.callOverridden();
oldTabCreation = mainwindow.createMainTabPanel;
mainwindow.createMainTabPanel = function() {
mainTab = oldTabCreation.apply(this);
mainTab.add(
Ext.create('Ext.panel.Panel',
{
title: 'Pricify',
layout: 'card'
})
);
return mainTab;
};
return mainwindow;
}
});
//{/block}
This works. I'm not sure, if it's the preferred way, but the View gets loaded at the right place and I'm quite happy (as it costs me several hours).
But there's some way to go.
How would I inject the entire logic here?
My requirements are:
I need a controller, a view and a store/model
Preferably in an own namespace
I want to separate my classes into files.
the file must reside in the plugin folder, not in the original app folder.
I could append code to the app.js file, but as far as I know, I can't attach controllers and views, nor would I know how to autoload the files.
Is there any preferred way of doing so?
EDIT
I'm now building a simple app, that's loaded before and try to inject the controllers that are then available into the app. I'll report back, once I'm ready.
Usually I would do something like this by intercepting controller events (with Ext.ux.Application override) and adding some logic on top of that. Alternatively you could extend existing controller and replace it with your custom one in the whole app, if that's feasible. Otherwise monkey patching could be the only way to extend an existing monolithic application that wasn't written with extensibility in mind.
Also, 4.2 Beta 2 should be available shortly; it includes a whole host of MVC improvements, including something like the override mentioned above. You may want to take a look at it.

Categories