How to Load Angular Controller Dynamically - javascript

I have an application with 10 views and several shared components
--app
-------components
-------------home
-----------------homeController.js
-----------------homeDirective.js
-----------------home.html
.
.
.
-------shared
----------modals
------------someModal
--------------- someModalController.js
--------------- someModal.html
the components load by angular routing
(function() {
'use strict';
angular
.module('app')
.config(appConfig);
function appConfig($routeProvider) {
$routeProvider.
when("/home", { templateUrl: "app/components/home/home.html", controller: 'homeController' })............
otherwise({ redirectTo: "/home" });
}
})();
the modals used in different components , all things are worked when the main page contains all script files. for example
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body ng-app="fleetCam" ng-controller="appController">
<div id="wrapper">
<div id="page-wrapper">
<ng-view>
</ng-view>
</div>
</div>
<!-- /#wrapper -->
<!-- jQuery -->
<script src="Scripts/jquery-2.1.4.min.js"></script>
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-route.js"></script>
<script src="Scripts/ngStorage.js"></script>
<script src="appMain/app.module.js"></script>
<script src="appMain/app.routes.js"></script>
<script src="appMain/app.services.js"></script>
<script src="appMain/app.directive.js"></script>
<script src="appMain/components/home/homeController.js"></script>
<script src="appMain/components/home/aboutController.js"></script>
<script src="appMain/shared/modal/insert/insertController.js"></script>
I looking for a way to remove the last three script tags and load controller or other dependencies on the fly. I have searched a lot about lazy loading but no one works in my context especially when I add shared components.

You could use the patterns from the async section on the official angular-seed repo: https://github.com/angular/angular-seed/#loading-angular-asynchronously
https://github.com/angular/angular-seed/blob/master/app/index-async.html
this relies on the ded/script "Async JavaScript loader & dependency manager" https://github.com/ded/script.js

Related

Angular Material and md-nav-bar routing

I'm digging into Angular and have decided to use the Angular Material library to assist in my first application. So far I have some very basic code I copied from https://material.angularjs.org/1.1.0/demo/navBar which I have modified to fit my own needs. I'm having some trouble wrapping my head around routing and the md-nav-items.
<html>
<head>
<title>PRT - CIT</title>
<meta name="viewport" content="width=device-width, initial-scale=1" </meta>
<!-- Angular Material style sheet -->
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.css">
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic"> </head>
<body ng-app="MyApp" id="bootstrap-overrides">
<div ng-controller="AppCtrl" ng-cloak="" class="navBardemoBasicUsage main">
<md-content class="md-padding">
<md-nav-bar md-selected-nav-item="currentNavItem" nav-bar-aria-label="navigation links">
<md-nav-item md-nav-click="goto('queue')" name="queue">Queue</md-nav-item>
<md-nav-item md-nav-click="goto('detail')" name="detail">Detail</md-nav-item>
<md-nav-item md-nav-click="goto('request')" name="request">Request</md-nav-item>
<!-- these require actual routing with ui-router or ng-route, so they won't work in the demo
<md-nav-item md-nav-sref="app.page4" name="page4">Page Four</md-nav-item>
<md-nav-item md-nav-href="#page5" name="page5">Page Five</md-nav-item>
--></md-nav-bar>
<div class="ext-content"> External content for `<span>{{currentNavItem}}</span>` </div>
</md-content>
</div>
<script src="node_modules/angular/angular.js"></script>
<script src="node_modules/angular-resource/angular-resource.js"></script>
<script src="node_modules/angular-animate/angular-animate.js"></script>
<script src="node_modules/angular-route/angular-route.js"></script>
<script src="node_modules/angular-aria/angular-aria.js"></script>
<script src="node_modules/angular-messages/angular-messages.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-114/svg-assets-cache.js"></script>
<script src="node_modules/angular-material/angular-material.js"></script>
<script src="js/site.js"></script>
<link rel="stylesheet" href="/css/site.css">
</body>
</html>
Here's my JS:
(function () {
'use strict';
var MyApp = angular.module('MyApp', ['ngMaterial', 'ngMessages', 'material.svgAssetsCache', 'ngRoute']).controller('AppCtrl', AppCtrl);
function AppCtrl($scope) {
$scope.currentNavItem = 'queue';
}
MyApp.config(function ($routeProvider) {
$routeProvider.when('/', {
templateUrl: '/index.html'
, controller: 'AppCtrl'
}).when('/queue', {
templateUrl: '/partials/queue.html'
, controller: 'AppCtrl'
}).when('/detail', {
templateUrl: '/partials/detail.html'
, controller: 'AppCtrl'
}).when('/request', {
templateUrl: '/partials/request.html'
, controller: 'AppCtrl'
});
});
})();
I'm kind of lost as to how I should route the tabs. From what I've read, md-nav-bar has some routing built in, but I've found examples utilizing ngRoute as well ui-router.
I'm also confused as to actually populate my partial views in the
<div class="ext-content"> External content for `<span>{{currentNavItem}}</span>` </div>
I tried using md-nav-href instead of md-nav-click but it just ended up redirecting me to the pages, not populating the content below my tabs/nav-bar; I rolled back the JS I had written and that part of the HTML. I've read the other questions posted in this area that I could find but none addressed rendering different partials based on nav-bar item. Any suggestions? I was thinking I could monitor currentNavItem and have the right partial render based on the value of it, but again, I'm not sure how to actually do the rendering.
Here is a Plnker that doesn't render correctly in the preview for some reason, but the code is the same as what I have locally.
Here is an image of what it looks like running locally.
Thanks in advance!
Final Edit:
S/O to #Searching for helping me get it working below. I've updated the plnker link to reflect the changes. Note it gets a little laggy due to the base append script.
ngRoute: When $route service you will need ng-view container. This will be used to load all you routed pages.
You do not have a goto() so just use simple md-nav-href tags to navigate around. The currentNavItem is set by md-selected-nav-item which is not what you need. Let's route with your setup
index.html : update your links to look like this. Use md-nav-href
<md-nav-item md-nav-href="queue" name="queue">Queue</md-nav-item>
index.html : when using html5Mode you will need base tag. Instead of manually specifying it just use the script below. Make sure you load angular.js before this script.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.js"></script>
<script type="text/javascript">
angular.element(document.getElementsByTagName('head')).append(angular.element('<base href="' + window.location.pathname + '" />'));
</script>
script : enable html5molde, why.. too many resources out there. I encourage you to lookup :)
MyApp.config(function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true)
$routeProvider.when('/', {
templateUrl : 'index.html',
controller : 'AppCtrl'
}).when('/queue', {
templateUrl : 'queue_partial.html',//actual location will vary according to your local folder structure
controller : 'AppCtrl'
}).when('/detail', {
templateUrl : 'detail_partial.html',
controller : 'AppCtrl'
}).when('/request', {
templateUrl : 'request_partial.html',
controller : 'AppCtrl'
});
});

Cannot get ng-controller to work in angular app

I've just started learning web development on my own, and I've run into an issue where either my entire app or just a controller just won't cooperate.
In prototype.js, I declare the app:
var cds = angular.module('cds', ['ngRoute']);
cds.config(function($routeProvider) {
$routeProvider
.when('/', {
controller: 'appCtrl',
templateUrl: 'partials/login.html'
})
.otherwise({
redirectTo: '/'
});
});
cds.controller('appCtrl', ['$scope', function($scope) {
$scope.pageClass = 'page-login';
$scope.list = [
{name: 'One', description: 'I'},
{name: 'Two', description: 'II'},
{name: 'Three', description: 'III'},
{name: 'One More', description: 'Extra'}
];
}]);
In my HTML file:
<!DOCTYPE html>
<html ng-app='cds'>
<head>
<title>References</title>
<meta charset="utf-8">
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script src="js/prototype.js"></script>
<style type="text/css">
#import url("styles.css");
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" href="css/font-awesome.css">
</head>
<body ng-controller='appCtrl' onload="align()" onresize="align()">
{{ pageClass }}
<div ng-view></div>
<div id="dropdown">
<button class="drop-btn">Options</button>
<div class="dropdown-content">
<img src="img/header.menu.png">
</div>
</div>
</body>
</html>
For some reason, {{ pageClass }} won't even display the value I assigned to it in the controller, let alone ng-view elements. Before, I had followed a very old routing tutorial where the app was declared using just angular.module('myApp', ...), and all controllers made as individual functions independent from the angular app, and everything worked fine for me. However, after jumping from angular 1.0.7 to 1.5.8 (it's a long story, and a newbie mistake), I tried updating the style and cleaning my code up, and this is what happened. I feel like I'm missing something very basic here.
Edit:
Turns out I forgot to include ng-route. Derp. Now everything's working perfectly. Thanks all!
Looks like you're missing the ngRoute module. You can link to it through the CDN:
http://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular-route.min.js
Here's a fiddle with the added dependency.
hey be sure to include ngRoute, and maybe put the script includes at the bottom of body... got your fiddle to work by doing so

Why are scripts tags not displayed in the inpector of browser if and when you put them inside div which has ng-view in angular js?

I am using angular routing. And my question is that, if I include Scripts tags in the div which has ng-view, the script tags are not displayed in the browser inspector. But, still everything works perfectly fine.
Now I am sure that it is a bad practice to include scripts inside ng-view. But still wanted to understand as to why this happens.
P.S. : The execution of scripts works fine. Its just that the browser Inspector does not show the scripts. Although the scripts are still there if I do a view source.
HTML
<html ng-app="imgPrcApp">
<head>
<title>Image Processing</title>
</head>
<body>
<div ng-view>
<script type="text/javascript" src="../javascripts/angular.js"></script>
<script type="text/javascript" src="../javascripts/angular-route.js"></script>
<script type="text/javascript" src="../javascripts/imgPrc.js"></script>
</div>
</body>
</html>
JS
var imgPrcApp = angular.module('imgPrcApp', ['ngRoute']);
imgPrcApp.config(['$routeProvider', '$compileProvider', function($routeProvider, $compileProvider) {
/**** Routing of HTML Templates ****/
$routeProvider
.when('/', {
templateUrl: '/assets/pages/qc.html',
controller: 'QCController'
})
.when('/editor', {
templateUrl: '/assets/pages/editor.html',
controller: 'editorController'
});
}])

Structuring templates in an AngularJS SPA - are there performance issues when using ng-include a lot?

I was wondering what the best way to structure templates in an AngularJS SPA. So far I have kind of a rails approach, but I'm not sure if this is a good idea.
What I mean is that I for example have a /js/app/views/partials folder where I have snippets of html that are used in different places. This could be a form or a preview of content, basically everything that is used all over the app. I like this structure because let's say you have a comment form that appears in 5 different places and you want to add a field: Changing one file rather than 5 is much better.
I then for example have a /js/app/views/home.html template, that is referenced by my ui-router and loaded in ui-view in /index.html which only serves as layout.
/js/app/routes.js
myModule.config([
'$stateProvider',
'$urlRouterProvider',
'$locationProvider',
function($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: '/js/app/views/home.html',
controller: 'MainCtrl',
resolve: {
// resolve code
}
});
}
]);
/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<base href="/">
<title><%= title %></title>
<link href="/css/bootstrap.min.css" rel="stylesheet">
<link rel='stylesheet' href='/css/style.css' />
<script src="/js/angularjs-1.3.16.min.js"></script>
<script src="/js/angular-ui-router-0.2.15.js"></script>
<script src="/js/app/app.js"></script>
<script src="/js/app/routes/routes.js"></script>
<script src="/js/app/services/services.js"></script>
<script src="/js/app/controllers/controllers.js"></script>
</head>
<body ng-app="myApp" ng-controller="MainCtrl">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</div>
</body>
</html>
/js/app/views/home.html
<div class="page-header">
<h1>v2</h1>
</div>
<div ng-include src="'/js/app/views/partials/post-form.html'"></div>
<div ng-repeat="post in posts">
<div ng-include src="'/js/app/views/partials/post-preview.html'"></div>
</div>
So the ui-router is called with the home state and injects the /js/app/views/home.html in /index.html (at ui-view). home.html itself includes two partials /js/app/views/partials/post-form.html and /js/app/views/partials/post-preview.html.
The result are a lot of XHR requests for a single page load. That cannot be good for performance.
Is there a better way to do that? Or can I just not structure my views with so many partials and have to use fewer files and repetitive code?
My backend / server is NodeJS with Express. So maybe it would also be an option to do that server-side, using express partials.

A simple angular js program to render different views is not working

Hi i am trying to write a simple Angular JS program but its not working
This is my html file:
<!DOCTYPE html>
<html data-ng-app="myApp">
<head>
<title>SPA APP</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
</head>
<body>
<div data-ng-view=""></div>
<script src="my-module.js"></script>
<script src="my-controller.js"></script>
</body>
</html>
This is my-module.js file
var myApp=angular.module('myApp',[]);
myApp.config(function($routeProvider){
$routeProvider
.when('/',
{
controller:'myController',
templateUrl:'view1.html'
})
.when('/view2',
{
controller:'myController',
templateUrl:'view2.html'
})
.otherwise({redirectTo:'/'});
});
And this is my-controller.js file
myApp.controller('myController',function($scope){
$scope.name="varun";
});
Any help will be appericiated.
In order to use Angular router, you need to include ngRoute module, which is not shipped by default with angular.js file.
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular-route.min.js"></script>
And then you need to declare dependency:
var myApp = angular.module('myApp', ['ngRoute']);
Having done this, you can use $route service in controllers, directives, etc. and $routeProvider in config section to set up routes.

Categories

Resources