I'm working on converting an existing patchwork app into an Angular app. The app is built on a CMS that bundles "components" together as packages that are reusable throughout the site, so the most effective solution right now is to bundle the relevant JS to a unique component as an inline <script> tag and leaving global functionality in a separate JS file that every page on the site shares. The CMS doesn't work well with SPA's yet.
One roadblock I have found is that I am declaring an ng-app="siteApp" on a shared template to all pages (hence every page has this app).
On a given .html page for a component, I have a controller ng-controller="RecipesCtrl" and want to tie it into my app. I can't reference siteApp on this internal page, even though it exists in a global context: https://docs.angularjs.org/error/$injector/nomod?p0=siteApp
If I include all the filters/controllers in the same .js file as siteApp, it works. If I put the controller on a different file that loads after siteApp, it can't find siteApp. Is there something obvious that I'm missing?
Thanks.
Without knowing the CMS it's hard to put a finger on anything but try chunking things into modules and injecting them as dependencies in siteApp.
Global JS file
angular.module('siteApp', [
'siteApp.recipes',
'siteApp.ingredients',
'siteApp.etc...'
]);
Component's JS file
angular.module('siteApp.recipes')
.controller('RecipesCtrl', [function () {
}]);
Related
I've been messing around with Angular and i wanted to split all the files up according to their role in my app.
I want a folder for each "page" like /home or /products and take care of everything within their respective folder(It sounded like a great idea).
However, now i'm not sure how to approach loading these files in or even where to do it.
This is my current file structure:
Due to certain limitations im not able to use other helpful tools, this needs to happen in the code directly.
What would be the best way to approach this?
1st part of your question:
There's no default way to organise your angular app.
However, there are some guidelines. I keep thanking myself for reading the Angular 1 app-structuring-guidelines by John Pappa which enlightened me on the same question you are asking.
At the moment, I have organised all my apps in a folder-by-functionality apprach rather than a folder-by-type one (i.e. all controllers in a controllers folder, all services in a services folder,etc).
2nd part of your question:
Just use Gulp or Grunt and then import the single file in your index
The Web is getting more and more component oriented, now all the most famous frontend frameworks adopt a reusable component policy (React and Angular 2 relies heavily on it)
If you want your angular app to be as modular as possible, you have to put everything regarding a component in a separate folder (html templates,css styles and js logic),and split the shared logic between services and assets
In Your case an example of project structure could be:
app/
assets/
//put here images,fonts and shared styles
services/
apiService.js
utilsService.js
etc etc ...
components
home/
home.js
home.css
home.html
products/
products.js
products.css
products.html
etc etc/...
index.js
index.html
The application has many small HTML files. Is there some way that I can concat these together into some kind of template and had them all at one time? I'm not sure if this would be AngularJS or ui-router functionality or if that option even exists. Looked and did not so far see any examples of people doing that with ui-router. Hope to get some good feedback or some examples.
Yes, it's possible. Suppose you have these two html files:
partials/foo.html, containing <h1>Hello</h1>
partials/bar.html, containing <h2>World</h2>
and those constitute the value of the templateUrl of two of your states.
You can generate a JS file containing that kind of code:
angular.module("templates").run(
function($templateCache) {
$templateCache.put('partials/foo.html', '<h1>Hello</h1>');
$templateCache.put('partials/bar.html', '<h2>World</h2>');
}
]);
If loaded, this JS file will thus prepopulate the cache used by angular to store the templates, and the router will thus not have to get them from the backend.
There are gulp (and probably grunt) plugins doing that for you at build time. A quick google search found this, for example: https://www.npmjs.com/package/gulp-angular-templatecache
I am starting a side-project based in Sails to try it. Most of the pages are server-side rendered via EJS and don't require javascript on the front-end (my landing page doesn't, my "about" page certainly doesn't etc). However, I have a few pages that have quite a lot client-side functionality and I want to use Angular, because I am mostly familiar with that framework. The routing to these pages is again handled in the server and there's really no meaning in bundling them as a SPA.
So I am trying to wrap my mind around these concerns:
Where to place the Angular app's scripts?
Is /assets/js/dependencies still the proper place? Wouldn't placing them there make the Grunt task inject them in layout.ejs and thus in every page?
How to conditionally load the Angular base and it's components (controllers, services, etc)?
Sails uses views/layout.ejs as a base layout for loading project-wide styles, templates and scripts. Each page's controller handles injecting the body part into this layout according to the view "partial" that has been developed for that page. Is this view "partial" .ejs file the appropriate place to conditionally load the Angular app files in only the pages that require them?
How to add min/conctact/uglify of Angular' script sources in Grunt tasking?
All the Angular related files will need to be concatenated, minified/uglified for production. This will need to be a new js concatenated file to be loaded in appropriate pages apart from the "generic" js file that currently Sails tasks create and is loaded in every page. So we're essentially talking about two concatenated js files for the client side. One that is globally loaded, and the Angular one that only the pages that need it load. Which parts of the build/tasking procedure will require modifications? Some examples or resources to check would be highly useful here.
Where to place the Angular app's scripts?
Is /assets/js/dependencies still the proper place?
No, just put your angular.min.js in your dependencies folder, but not your Angular app's script. You need to put all you Angular app in the assets/js folder ( or in a sub-folder, but not in dependencies )
To be sure that each file of your app will be loaded in the right order (for example you need to load first the Js file which inject your angular app's dependencies), you can modify the tasks/pipeline.js file, and specify the order you want : You need to modify the jsFilesToInject array which contains all the Js files to load in the right order.
For example for your project :
var jsFilesToInject = [
// Load sails.io before everything else
'js/dependencies/sails.io.js',
// loading angularJS
'js/dependencies/angular.min.js',
// all the rest in dependencies
'js/dependencies/**/*.js',
// loading first AngularModule definition
'js/app/app.module.js',
// all the rest of the angular application
'js/app/**/*.js'
];
For your other question I think you need to look at the tasks/config/sails-linker.js file, that inject all the Js scripts in the <!--SCRIPTS--> tags in your HTML code.
I hope that it will help you and that I'm not too late !
I'm developing an application with this structure
App
Pages
Profile
Account
etc...
Modules
nameOfModule
nameOfModule
etc
In the Pages directory I've got all the different pages in the application, switching between these pages will cause reloads.
In each of these pages directories, for example Profile, I've got 3 files(may differ)
router.js
main.js
app.js
main.js is called using requireJS and the only thing it does in set some paths for the dependencies and then it just calls the initialize() located in app.js wich in turn simply initializes the router in router.js.
My problem is, how and where do I connect the modules to the actual page?
Lets say I've got a few modules that are supposed to show up on the Profile page, lets call them Module1, Module2 and Module3, where do I organize these modules for the page?
It feels wrong to organize these kind of things in the router? Where do I decide wich modules I use and where they go?
You may consider using Marionette's Module to help you
https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.application.module.md#starting-and-stopping-modules
I recently started to digg in to angularjs, and would help me a lot with my new project, but im stucked with the view structure part.
So what i dont really understand is, how to build it up.
Is it okay if i create html angular partials and not creating laravel views, so laravel would only handle the database instert fecth edit delete, and the angular partial views would handle the result show, and forms.
So my buold up would look like this.
My assets folder
/css
/img
/js
/lib
/partials
/home
index.html
/users
users.html
details.html
And creating restful controllers for them what handlets listed above
Or if someone could show my a basic exaple about this, just the controller and view part, how to build up a singple page with showing result, and one with grabing by id i would really be grateful.
Thank you
When starting a Laravel & AngularJS project you are in charge of the backend and frontend. Basically you have 3 options.
Keep the entire app in the same folder, and the angularjs stuff in the public folder.
Keep the entire app in the same folder and AngularJS views in the laravel view folder.
Separate your backend and frontend completely.
The first & second option are the simplest, and its OK if you have a small/medium sized application. In this case just keep all the AngularJS files in the public folder, or if you choose to mix them with laravel views just drop the .blade extension (or change the laravel blade/angularjs template syntax)
I see its best to keep the backend as restful as possible when doing a SPA app, the point is to push the logic to the browser, this means your app can become a mess if you mix php with js too much.
The folder structure is totally up to you, and it does not matter what option you choose. But a good start is separating you app into a logical parts.
/app
application.js
/partials
user.html
login.html
etc.html
/vendor
Angular.js
Lodash.js
Etc.js
/controllers
User.js
Etc.js
/directives
Charts.js
Etc.js
/filters
Custom.js
Etc.js
/services
Backend.js
Etc.js
You can also check this for a good angularjs styleguide.
The above is a basic folder structure, just customize it as you see best. If you have a small app, you could drop the folders and just have a controllers.js directives.js and services.js (etc)and keep all your javascript in the same file. This is totally up to you. Separate when the application grows, and always refactor.
If you choose the third option you will have to customize the backend a bit. This might be the hardest option, but it also gives you great flexibility. Basically you could drop laravel all together, and build the backend in node.js, or use laravel as a backend for another SPA app written in Ember.js without making any changes in the code. Note if you are choosing this option you cannot make use of some laravel stuff, like the blade templating. You will also have to setup your laravel app for CORS, and note, there can be some more coding when it comes to security, like CSRF tokens and such.
When going to production with you app you can use a build tool to min & concat you frontend app into one file. Checkout ng-min for minification.
This is one of the project I am working on. You can see the way how I have partial views in angular js. As suggested above, there is no need putting your view files in public folder.
https://github.com/naveensky/wm-demo-tracker