Some confusion regarding AngularJS architecture - angularjs

Recently I bought a fuse AngularJS theme from http://themeforest.net/item/fuse-angularjs-material-design-admin-template/12931855 but what kind of AngularJS architecture does this code follow? All Files Are Separate modules, controller and HTML file, and it uses gulp to run
This is Module
(function ()
{
'use strict';
angular
.module('app.components.tables.datatable', [])
.config(config);
/** #ngInject */
function config($stateProvider)
{
$stateProvider.state('app.components_tables_datatable', {
url : '/components/table/datatable',
views : {
'content#app': {
templateUrl: 'app/main/components/tables/datatable/datatable.html',
controller : 'DatatableController as vm'
}
},
resolve: {
Employees: function (apiResolver)
{
return apiResolver.resolve('tables.employees100#get');
}
}
});
}
})();
This is Controller
(function ()
{
'use strict';
angular
.module('app.components.tables.datatable')
.controller('DatatableController', DatatableController);
/** #ngInject */
function DatatableController(Employees)
{
var vm = this;
// Data
vm.employees = Employees.data;
vm.dtOptions = {
dom : '<"top"f>rt<"bottom"<"left"<"length"l>><"right"<"info"i><"pagination"p>>>',
pagingType: 'simple',
autoWidth : false,
responsive: true
};
// Methods
//////////
}
})();

Here is a good documentation which helps to start with Fuse theme's angular version.
http://withinpixels.com/themes/fuse/documentation/getting-started/introduction
It uses modular structure under /app directory. To add a new module, simply put your module files into your preferred location inside the app/ directory and then add the module name as a dependency into the app/index.module.js file.
Unzip the zip file that you have downloaded from Themeforest. Inside the zip file, you will find the Skeleton Project (Fuse-1.x.x.zip) along with the Demo Project (Fuse-1.x.x-demo.zip), PSD designs and a readme file. After extracting Fuse-1.x.x.zip or Fuse-1.x.x-demo.zip, you will find /src folder where you need to build your modules under /app folder. After completing you need to run "gulp build" (for production) or "gulp build:dev" (for development). Finally you will get your build theme under /dist folder. Now you can use it in any where. Even you can run using apache server.

Related

AngularJS in Laravel using Elixir

I am trying to setup a Laravel and Angular application. I wanted to place my work files under resources/assets/js and then use webpack and elixir to compile those code and create a single app.js file in my public directory. But I am not sure how to do that? Can anyone guide me with a step based approach for it?
Here is a gulp only process
No webpack used. Please anyone can rewrite this with Laravel Mix I would really appreciate.
1- Install npm modules
`npm i --S bower gulp gulp-concat gulp-uglify`
2- Install Angular with bower
bower install --save angular angular-sanitize angular-ui-router
3- Now that you have your angular assets in bower_components, create a file at the root of your project to load all vendors. Let's create /vendor.json
[
"bower_components/angular/angular.min.js",
"bower_components/angular-sanitize/angular-sanitize.min.js",
"bower_components/angular-route/angular-route.min.js"
]
Add all your vendors to that file. Bower or Npm vendors. Anything you download that is not part of your code.
4- Go to /gulpfile.js and add a task
var gulp = require('gulp),
concat = require('gulp-concat'),
uglify = require('gulp-uglify');
gulp.task('vendorjs', function() {
var source = require('./vendorjs.json');
return gulp.src(source)
.pipe(concat('vendors.min.js'))
.pipe(uglify())
.pipe(gulp.dest('public/assets/js'))
});
That task will compile all vendors assets to /public/assets/js/vendors.min.js
5- In resources/assets/js, create following directories controllers, modules and the file app.js. Inside of app.js do
// 'resources/assets/js/app.js'
(function(){
angular
.module('myApp', ['app.core', 'app.controllers']);
})();
6- In the modules directory create core/module.js. This is the core module where you load all external modules loaded via bower or npm.
// 'resources/assets/js/modules/core/module.js'
(function(){
angular
.module('app.core', ['ngRoute', 'ngSanitize']);
})();
7- Still in the modules directory create controllers/module.js. All your controllers will be bound to this module.
// 'resources/assets/js/modules/controllers/module.js'
(function(){
angular
.module('app.controllers', []);
})();
8- Now you can write your controllers like this
// 'resources/assets/js/controllers/home.js'
(function(){
angular
.module('app.controllers')
.controller('HomeController', Controller);
//Use injection for assets minification
HomeController.$inject = ['$scope', '$http'];
function HomeController($scope, $http)
{
var vm = this;
activate();
function activate()
{
vm.sayHi = function() {
console.log('Hi');
}
}
}
})();
9- If you want to define routes
// 'resources/assets/js/modules/routes/routes.js'
(function(){
angular
.module('app.routes', [])
.config(routesConfig);
//Use injection for assets minification
routesConfig.$inject = ['$stateProvider', '$locationProvider', '$urlRouterProvider'];
function routesConfig($stateProvider, $locationProvider, $urlRouterProvider)
{
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: '/templates/home.html',
controller: 'HomeController'
})
...
}
})();
10 - Create angular task in gulpfile
gulp.task('angular', function() {
var root = 'resources/assets/js';
var source = [
root + '/app.js',
root + '/modules/**/*module.js',
root + '/controllers/**/*js'
];
return gulp.src(source)
.pipe(concat('app.min.js'))
.pipe(uglify()) //comment this line when in development
.pipe(gulp.dest('public/assets/js'))
});
I think that's it. I may have made one or 2 typos, but angular that's the gist of it. How I use gulp with laravel for angular
I couldn't do this from scratch but there is a package that uses lumen, angular2. Providing a link for the same so anyone with the same problem can be benefited. Link: anvel.io

How to copy partial templates in BlurAdmin/angular.js using gulp serve:dist

I'm quite new in terms of gulp, but what I need is to deploy my BlurAdmin panel (https://github.com/akveo/blur-admin) to production with partial templates just copied and not embedded into js files.
When I launch:
gulp serve:dist
I get my results in "release" folder and everything works file. How can I modify build.js file to copy all *.html partial templates (i.e. https://github.com/akveo/blur-admin/blob/master/src/app/pages/dashboard/blurFeed/blurFeed.html) to release folder without embedding them into app-caf1fdab53.js or similar?
Not sure why -1, as I mentioned I'm rookie in gulp.
I solved it even better as I originally wanted. In directive file, instead of static html file I added URL my my REST service and I serve HTML files from there
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.directive('dashboardKafkaEvents', [ function dashboardKafkaEvents() {
return {
restrict: 'E',
controller: 'DashboardCtrl',
controllerAs: 'mc',
templateUrl: http://hostname:port/template/mytemplate
};
}])
})();

Gulp and wire dep not injecting file type *.*.js files

I am facing below issue -
I have Yeomen generator and wiredep to inject bower dependencies in index.html file.
I have installed angular tree view by bower then noticed that lib files and css file of angular tree view are not getting injected in index file.
After debugging for while found that the lib file of angular tree view has one extras dot (angular.treeview.js) same with the css file as well
So how to inject that file in index.html
i have below task in inject.js file in gulp folder to inject file in index.html which is generated by yoemen
gulp.task('inject', ['scripts'], function () {
var injectStyles = gulp.src([
path.join(conf.paths.src, '/app/**/*.css')
], { read: false });
var injectScripts = gulp.src([
path.join(conf.paths.src, '/app/**/*.module.js'),
path.join(conf.paths.src, '/app/**/*.js'),
path.join('!' + conf.paths.src, '/app/**/*.spec.js'),
path.join('!' + conf.paths.src, '/app/**/*.mock.js')
])
.pipe($.angularFilesort()).on('error',conf.errorHandler('AngularFilesort'));
var injectOptions = {
ignorePath: [conf.paths.src, path.join(conf.paths.tmp, '/serve')],
addRootSlash: false
};
return gulp.src(path.join(conf.paths.src, '/*.html'))
.pipe($.inject(injectStyles, injectOptions))
.pipe($.inject(injectScripts, injectOptions))
.pipe(wiredep(_.extend({}, conf.wiredep)))
.pipe(gulp.dest(path.join(conf.paths.tmp, '/serve')));
}
I am using Yeomen and gulp.
Any help would be appreciated.
It doesn't have to do anything with your gulp task.
Wiredep uses bower.json file to inject dependency in your index file.
I case of any issue, like in your current scenario you just need to override your package, like you do for bootstrap.
add below code in bower.json
"overrides": {
"bootstrap": {
"main": [
"dist/css/bootstrap.css",
"dist/fonts/glyphicons-halflings-regular.eot",
"dist/fonts/glyphicons-halflings-regular.svg",
"dist/fonts/glyphicons-halflings-regular.ttf",
"dist/fonts/glyphicons-halflings-regular.woff",
"dist/fonts/glyphicons-halflings-regular.woff2"
]
},
"angular-treeview":{
"main":[
"angular.treeview.js",
"css/angular.treeview.css"
]
}
}
I hope it will help you.
Happy coding :)

AngularJS- Dynamic Loading of script files using LazyLoad- Webpack

Right now in my index.html page I have links to two CDN files one being a JS and the other a CSS file.
i.e.
in the the bottom of my body
https://somedomain.com/files/js/js.min.js
and in the head
https://somedomain.com/files/css/css.min.css
But right now they aren't needed on my homepage but just in one particular route. So I was looking into how I can lazy load these CDN resources when that routes gets hit i.e. /profile and only then ?
These aren't installed via bower or npm but just loaded via CDN url for example jquery. How in Angular 1 and Webpack can I lazy load that based on a route ?
Here you go.. It is made possible using oclazyload. Have a look at below code. A plunker linked below
I have a module Called myApp as below
angular.module('myApp', ['ui.router','oc.lazyLoad'])
.config(function ($stateProvider, $locationProvider, $ocLazyLoadProvider) {
$stateProvider
.state("home", {
url: "/home",
templateUrl: "Home.html",
controller: 'homeCtrl',
resolve: {
loadMyCtrl: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load('homeCtrl.js');
}]
}
})
.state("profile", {
url:"/profile",
templateUrl: "profile.html",
resolve: {
loadMyCtrl: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load('someModule.js');
}]
}
})
});
I have another module called someApp as below
(function () {
var mynewapp=angular.module('someApp',['myApp']);
mynewapp.config(function(){
//your code to route from here!
});
mynewapp.controller("profileCtrl", function ($scope) {
console.log("reached profile controller");
});
})();
I have a Live Plunker for your demo here
I have this JStaticLoader repo, to ease me loading static files whenever I need them. Though, it's not angularized, but you can still use it in your app as a directive, direct call it from your controller or even in the $rootScope to load your desired js.
JStaticLoader uses pure js and require no dependencies. It uses XMLHttpRequest to load the static files.
As an example use in your app.js (on $routeChangeStart or $stateChangeStart)
myApp
.run(['$rootScope', '$http', function ($rootScope, $http) {
var scriptExists = function (scriptId) {
if (document.getElementById(scriptId)) {
return true;
}
return false;
};
var addLazyScript = function (scriptId, url) {
if (scriptExists(scriptId)) return;
var js = document.createElement('script'),
els = document.getElementsByTagName('script')[0];
js.id = scriptId;
js.src = url;
js.type = "text/javascript";
els.parentNode.insertBefore(js, els);
};
$rootScope.$on('$routeChangeStart', function (e, current) {
if (current.controller === 'MainCtrl') {
var pathUrls = ["https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/js/materialize.js"],
scriptId = 'lazyScript1';
if (scriptExists(scriptId)) return;
JStaticLoader(pathUrls, { files: ['js'] }, function (vals, totalTime) {
/* Success */
for (var i = 0; i < vals.length; i++) {
var path = vals[i];
addLazyScript(scriptId, path);
}
}, function (error, totalTime) {
/* Error */
console.warn(error, totalTime);
});
}
});
}]);
On the sample above, I get a js file by using xhr, and append it as a script in my document once it's finished. The script will then be loaded from your browser's cache.
Strictly talking about the Webpack -
Webpack is just a module bundler and not a javascript loader.Since it packages files only from the local storage and doesn't load the files from the web(except its own chunks).ALthough other modules may be included into the webpack which may do the same process.
I will demonstrate only some of the modules which you can try,as there are many such defined on the web.
Therefore a better way to lazy load the cdn from the another domain would be using the javascript loader - script.js
It can be loaded in the following way -
var $script = require("script.js");
$script = ("https://somedomain.com/files/js/js.min.js or https://somedomain.com/files/css/css.min.css",function(){
//.... is ready now
});
This is possible because the script-loader just evaluates the javascript in the global context.
References here
Concerning about the issue of lazy loading the cdn into the angular app
The following library Lab JS is made specifically for this purpose.
It becomes very simple to load and bloack the javascript using this library.
Here is an example to demonstrate
<script src="LAB.js"></script>
<script>
$LAB
.script("/local/init.js").wait(function(){
waitfunction();
});
<script>
OR
You can use the require.js
Here is an example to load the jquery
require.config({
paths: {
"jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min"
},
waitSeconds: 40
});
You should also consider the following paragraph from this article.
Loading third party scripts async is key for having high performance web pages, but those scripts still block onload. Take the time to analyze your web performance data and understand if and how those not-so-important content/widgets/ads/tracking codes impact page load times.

r.js cannot resolve dependencies mentioned in shim

I've recently joined a project which is built using Backbonejs, (uses Marionette for view rendering) + nodejs. They also use requirejs to load the backbonejs files. Would like to add at this stage, that I've never worked with backbonejs or requirejs before and hence I'm struggling with the issue I describe later.
Some code that will help explain the issue that I run into (All this code was already written by previous dev's)
Folder Structure:
/public
/js
/collection (consists all Backbone.js collections files)
/lib
/bower_components
/backone
/marionette
/etc
/models (consists all Backbone.js models files)
/views (consists all Backbone.js view files)
/main.js
/main.build.js
/app.js
/controller.js
/router.js
Code from files that I think relate to issue:
main.js
requirejs.config({
paths: {
'async': 'lib/bower_components/requirejs-plugins/src/async',
'jquery': 'lib/bower_components/jquery/dist/jquery.min',
'underscore': 'lib/bower_components/underscore/underscore-min',
'lodash': 'lib/bower_components/lodash/dist/lodash.min',
'backbone': 'lib/bower_components/backbone/backbone',
'marionette': 'lib/bower_components/marionette/lib/backbone.marionette.min',
'markercluster':'lib/markercluster',
'jquerymobile': 'lib/jquery.mobile-1.4.0.min',
'hogan': 'lib/template-2.0.0.min',
'templates': '/templates',
'real': 'lib/mainjs',
'touch': 'lib/jquery.touchSwipe.min',
'mouse': 'lib/jquery.mousewheel',
'moment': 'lib/moment-2.5.1.min',
'humanize': 'lib/bower_components/humanize-plus/public/dist/humanize.min',
'validator': 'lib/bower_components/validator-js/validator.min',
'real': 'lib/mainfile'
},
shim: {
backbone: {
deps: ["underscore"]
},
marionette: {
deps: ["backbone"]
},
templates: {
deps: ["hogan", "jquery"]
},
real: {
deps: ["jquery", "jquerymobile", "touch", "mouse"]
},
markercluster: {
exports: "MarkerClusterer"
},
humanize: {
exports: "humanize"
}
},
waitSeconds: 0
});
define('gmaps', ['async!http://maps.google.com/maps/api/js?v=3&key=AIzaSyBiV8f88yLWJ_IMSdP1fVNO1-gt3eLVSgg&sensor=true&callback=gMapsCallback'], function(){
// define('gmaps', ['http://maps.google.com/maps/api/js?v=3&sensor=false'], function(){
return window.google.maps;
});
require(['app', 'templates', 'real'], function(app) {
app.start({
version: "0.9.9"
});
});
main.build.js
({
baseUrl: ".",
name: "main",
wrapShim: true,
out: "main-built.js"
})
app.js
define(['underscore', 'controller', 'router', 'models/Cache', 'views/RootView'], function(_, Controller, Router, Cache, RootView) {
var Application = Marionette.Application.extend({
propertyListPageSize: 3,
initialize: function() {
_.templateSettings = { interpolate : /\{\{(.+?)\}\}/g };
},
onStart: function(options){
new RootView();
this.controller = new Controller();
this.router = new Router({controller: this.controller});
this.cache = new Cache();
this.context = {};
//this.evHistory = [];//#todo remove once BB/marionette navigation is in place
if(Backbone.history) Backbone.history.start({ pushState: false });
if(Backbone.history.fragment === "") this.navigate('home');
},
navigate: function(fragment, trigger, replace){
this.router.navigate(fragment, {trigger:trigger, replace:replace});
},
back: function() {
window.history.back();
}
});
app = new Application();
return app;
});
rootView.js
define(['marionette', 'views/HomeView', 'views/HeaderView', 'views/FooterView', 'views/MenuView', 'views/VideoView', 'views/LocationSearchView', 'views/LoginView', 'views/FindView', 'views/ServicesView', 'views/ValueView', 'views/PropertyListView', 'views/SideBySideView', 'views/ConfirmRegistrationView', 'views/ForgotPasswordView', 'views/CreateAccountView', 'views/UserHomeView', 'views/MyBrokerView', 'views/GiveFeedbackView', 'views/SeeFeedbackView', 'views/ViewingScheduleView', 'views/MyViewingsSummaryView', 'views/MyAccountView', 'views/ViewingConfirmView', 'views/ValueAddressPropertyListView'],
function(Marionette, HomeView, HeaderView, FooterView, MenuView, VideoView, LocationView, LoginView, FindView, ServicesView, ValueView, PropertyListView, SideBySideView, ConfirmRegistrationView, ForgotPasswordView, CreateAccountView, UserHomeView, MyBrokerView, GiveFeedbackView, SeeFeedbackView, ViewingScheduleView, MyViewingsSummaryView, MyAccountView, ViewingConfirmView, ValueAddressPropertyListView) {
var RootView = Marionette.LayoutView.extend({
...some view code
});
Use case I'm trying to solve:
So when I access the site in the browser, I notice in the debugger that it loads all the js files right at the beginning. During the load process my site is blank and user has to wait a while before he can use the site.
So what I've been able to understand is that when app is 'started' in main.js, app.js creates an instance of rootView.js , which in turn has all the views listed as dependencies. This triggers a download request for all the other views which in turn would solve their own dependencies and download all the relevant models and collections. Hence all files being downloaded when the user accessed the site.
Solution I've been trying:
Since requirejs is being used, I'm trying to use r.js to optimize and combine all the js files to reduce the number of downloads.
Issue I'm running into:
When i run r.js. i get the following error
Tracing dependencies for: main
Error: ENOENT: no such file or directory, open '/var/node_projects/rm/rm.src.server/src/public/js/underscore.js'
In module tree:
main
app
Error: Error: ENOENT: no such file or directory, open '/var/node_projects/rm/rm.src.server/src/public/js/underscore.js'
In module tree:
main
app
at Error (native)
If I add the underscore.js files directly to the specified path in the error, then I get the same error for marionette.js. What I think is happening is that app.js is not recognizing the shim'ed dependencies and hence its trying to find the files directly at specified path in the error.
Things I've tried:
- I've added wrapShim: true in the main.build.js file but that did not help
Honestly, I've been sitting on this for a couple of days and I'm not sure what I can do next and hence this post.
Any help/direction would be appreciated.
You need to include the same shim configuration in your build file, as wrapShim is not sufficient.
If shim config is used in the app during runtime, duplicate the config here. Necessary if shim config is used, so that the shim's dependencies are included in the build. Using "mainConfigFile" is a better way to pass this information though, so that it is only listed in one place. However, if mainConfigFile is not an option, the shim config can be inlined in the build config.
https://github.com/jrburke/r.js/blob/master/build/example.build.js

Resources