I am using webpack for bundling, and i have 4 module in angularJS(lets assume Management,Student,Teacher and Admin) so i have few js files names common in both management and admin. i am using webpack to create a single "bundle.min.js" file.
Now suddenly i add a feature to admin and i reload the page and find the ui-state router calling management controller insted of calleing admin controller.
my admin config file:
...
.state('admin',{
url:'',
views:{
'main':{
templateUrl:'adminPage.html',
controller:'AdminPageCtrl',
controllerAs:'$admin'},
}
})
...
config of management module
...
.state('management',{
url:'',
views:{
'main':{
templateUrl:'manPage.html',
controller:'AdminPageCtrl',
controllerAs:'$manage'},
}
})
...
admin index.js where i load all config and controllers:
var angular = require('angular'),
config = require('./config'),
adminPageCtrl= require('./controller/AdminPageCtrl');
module.exports = angular
.module('myApp.admin',[])
.controller('AdminPageCtrl', adminPageCtrl)
management index.js i load all config and controllers:
var angular = require('angular'),
config = require('./config'),
adminPageCtrl= require('./controller/AdminPageCtrl');
module.exports = angular
.module('myApp.management',[])
.controller('AdminPageCtrl', adminPageCtrl)
app.js where i load all modules
var angular = require('angular'),
adminModule = require('./admin/index'),
managementModule = require('./management/index'),
angular.module('myApp',['myApp.admin','myApp.management'])
The above is calling AdminPageCtrl of management module, instead of AdminPageCtrl of admin module.
Related
I want to store Url in configuration file so when I deployed this on Testing server or on Production I have to just change the url on config file not in js file but I don't know how to use configuration file in angular js
You can use angular.constant for configurations.
app.constant('appConfigurations', {
link_url: "http://localhost:8080/api",
//For production u can simply change the link_url
//link_url: "http://production_url/api"
});
There are ways you can deal with it , but while coming to our implementation we used to do the following way
Create an External Environment js file
(function (window) {
window.__env = window.__env || {};
window.__env.apiUrl = 'your Api Url';
}(this));
In your Index.html
add env.js above the app.js
<!-- Load environment variables -->
<script src="env.js"></script>
In your app.js
var envr ={};
if(window){
Object.assign(envr,window.__env)
}
// Define AngularJS application var app= angular.module('myapp', []);
// Register environment in AngularJS as constant app.constant('__env',
env);
Update:
For adding additional URl in Config File:
(function (window) {
window.__env = window.__env || {};
window.__env.apiUrl = 'your Api Url';
//Another Url
window.__env.baseUrl ='/';
}(this));
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
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.
I have an AngularJS project packed into a bundle with Webpack. I packed tempaltes into the bundle with ng-template-loader and html-webpack-loader.
Now I'm running it in webpack-dev-server and when I visit /home page, which needs components/home/home.html template, the browser fails with:
GET http://localhost:8001/components/home/home.html 404 (Not Found)
But when I look into the webpack bundle, everything seems fine:
function routes($stateProvider) {
$stateProvider.state("home", {
url: "/home",
// parent: "application-layout",
templateUrl: __webpack_require__(20), //templateUrl.html,
controller: "HomeController"
});
}
exports.default = _angular2.default.module("home", []).controller('HomeController', HomeController).config(routes);
/***/ },
/* 20 */
/***/ function(module, exports) {
var path = '/components/home/home.html';
var html = "<!-- Header -->\n<div id=\"header\" ng-include=\"'components/header/header.html'\"></div>\n\n<!-- Navigation -->\n<aside id=\"menu\" ng-include=\"'components/navigation/navigation.html'\"></aside>\n\n<!-- Main Wrapper -->\n<div id=\"wrapper\">\n \n Custom content will go here.\n \n <!-- Right sidebar -->\n <div id=\"right-sidebar\" ng-include=\"'components/right_sidebar/right_sidebar.html'\" class=\"sidebar-open\" ng-show=\"rightSidebar\"></div>\n \n <!-- Footer -->\n <footer class=\"footer\" ng-include=\"'components/footer/footer.html'\"></footer>\n \n</div>";
window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
module.exports = path;
What might be wrong?
The problem here is that module 20 is not defined as Angular module but is required from config block.
Once bootstrapping process has started, new items can't be added to Angular modules, calls to module methods (angular.module('ng').run in this example) will be ignored.
I have following code to cache the template. I am using gulp to pre-cache the templates. But I am not able to used it for router urls.
'use strict';
var config = require('../config');
var gulp = require('gulp');
var templateCache = require('gulp-angular-templatecache');
// Views task
gulp.task('views', function() {
// Put our index.html in the dist folder
gulp.src('app/**/*.html')
.pipe(gulp.dest(config.dist.root));
// Process any other view files from app/views
return gulp.src(config.views.src)
.pipe(templateCache({
standalone: true
}))
.pipe(gulp.dest(config.views.dest));
});
//in router
app.config(function($routeProvider) {
$routeProvider.when('/todos', {
templateUrl: 'views/todos.html',
controller: 'TodoCtrl',
});
});
Can anybody help me on how can i use the cached template in this router?
I got the issue. While template cache we have to five the actual path of the templates else it will take the relative url. If your templates are in views directory then we have to update it like this...
templateCache({
root:'views',
standalone: false
})