angularjs, load template and controller partialy using lazy load - angularjs

Please help me,
I was get an error when loading partialy template view and controller in angularjs using lazyload.
I got these error message:
Error: ng:areq
Bad Argument
Argument 'meSygroupController' is not a
How to fix it, when I will build big project, so its imposible to load all javascript controller in one time while load first page. And how to apply new controller to existing module
Here some codes :
Filename : angular-app.js
var colorAdminApp = angular.module('colorAdminApp', [
'ui.router',
'ui.bootstrap',
'oc.lazyLoad'
]);
colorAdminApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/app/dashboard/v2');
$stateProvider
.state('app', {
url: '/app',
templateUrl: 'demo?page=template/app',
abstract: true
})
.state('app.sys', {
url: '/system',
template: '<div ui-view></div>',
abstract: true
})
.state('app.sys.sygroup', {
url: '/sygroup',
templateUrl: 'me_sygroup',
// controller: "meSygroupController",
data: { pageTitle: 'Master Grup Akses' },
resolve: {
service: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load({
serie: true,
files: [
'me/meSygroupController.js',
'coloradmin/assets/plugins/jquery-jvectormap/jquery-jvectormap-1.2.2.css',
]
});
}]
}
})}]);
colorAdminApp.run(['$rootScope', '$state', 'setting', function($rootScope, $state, setting) {
$rootScope.$state = $state;
$rootScope.setting = setting;
}]);
And here template :
<div ng-controller="meSygroupController" class="frm">
<!-- <div> -->
<ol class="breadcrumb pull-right">
<li>Beranda</li>
<li>Sistem</li>
<li class="active">Grup User</li>
</ol>
<h1 class="page-header">Grup User <small>kelompok otorisasi user...</small></h1>
<!-- begin panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<div class="panel-heading-btn">
<i class="fa fa-expand"></i>
<i class="fa fa-repeat"></i>
<i class="fa fa-minus"></i>
<i class="fa fa-times"></i>
</div>
<h4 class="panel-title">Daftar Grup User</h4>
</div>
<div class="panel-body">
Panel Content Here
</div>
</div>
<!-- end panel -->
</div>
And here the controller
colorAdminApp.controller('meSygroupController', function($scope, $rootScope, $state) {
angular.element(document).ready(function() {});
$scope.test = function() { alert(111); }
$scope.test();
});
Please Helpme.
Arif Diyanto

Related

Angular UI-Router: nested views

I have two col layout with header and footer. Header has page navigation (GetStarted, Component). Of the 2 columns, one is for sidenav and other is for main content.
When "GetStarted" nav is active, sidenav is populated with respective links (overview, examples)
When "Component" nav is active, sidenav is populated with respective links (checkbox, alert)
Upon clicking "Overview" link area is populated with its data
<ul class="nav nav-tabs">
<li role="presentation" class="active">Default</li>
<li role="presentation">Disabled</li>
</ul>
<section class="content__main__tab__content col-xs-12 col-sm-12 col-md-12 col-lg-12">
<form id="checkbox--default">
<div class="input__checkbox--default" id="checkbox--default">
<!-- <div class="form-group"> -->
<fieldset>
<legend>Default</legend>
<label for="gi-checkbox">Checkbox Label
<div class="checkbox-input-wrapper group__input-wrapper">
<input type="checkbox" class="checkbox" id="gi-checkbox">
</div>
</label>
</fieldset>
<!-- </div> -->
</div>
</form>
</section>
Main content has 2 nav tabs for checbox states (default & disable). By clicking the "default" its content must be displayed and same goes for disabled. I'm new to angular and I kinda got first level nested view working. But couldn't the whole thing working. here is the code sample
index.html
<body ng-app="mendouiApp" id="mendo__home" data-spy="scroll" data-target=".scrollspy">
<nav class="navbar navbar-fixed-top navbar-inverse">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" ui-sref="home"><img src="images/gi-logo.png" alt="logo"/></a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a ui-sref="home">Get Started</a></li>
<li><a ui-sref="components">Components</a></li>
</ul>
</div><!-- /.nav-collapse -->
</div><!-- /.container -->
</nav><!-- /.navbar -->
<div class="wrapper" ui-view></div> <!--/.container-->
component.html
<div class="content__wrapper">
<div class="row">
<div class="content__secondary content__secondary--l scrollspy">
<ul id="sidenav-fixed-l" class="nav hidden-xs hidden-sm affix-top" data-spy="affix">
<li>
<h5>COMPONENTS</h5>
</li>
<li ng-repeat="item in componentsList">
<a ui-sref="{{item.link}}" ng-cloak>{{item.name}}</a>
</li>
</ul>
</div>
<div ui-view></div>
</div> <!--/.row-->
</div> <!--/.content-wraper-->
app.js
(function(){
var mendouiApp = angular.module('mendouiApp', ['ui.router', 'ui.router.stateHelper']);
mendouiApp.constant('COMPONENTS_LIST', {
name: 'sidenav',
templateUrl: '../components/components.list.html',
abstract: true,
children: [{
name: 'alerts',
url: '/alerts',
templateUrl: '../components/alerts/alerts.html'
}]
});
mendouiApp.config(function($stateHelperProvider, $urlRouterProvider, $locationProvider, $urlMatcherFactoryProvider, COMPONENTS_LIST) {
$urlMatcherFactoryProvider.strictMode(false);
$urlRouterProvider.otherwise('/home');
$locationProvider.hashPrefix('!');
$stateHelperProvider
.state('home', {
url: '/home',
templateUrl: '../gettingstarted.html',
controller: 'getStartedController'
})
.state('layouts', {
url: '/layouts',
templateUrl: '../layouts.html'
})
.state('screenpatterns', {
url: '/screenpatterns',
templateUrl: '../screenpatterns.html'
})
.state('yogi', {
url: '/yogi',
templateUrl: '../yogi.html'
})
.state('components', {
url: '/components',
templateUrl: '../components.html',
controller: 'componentsController'
})
.state(COMPONENTS_LIST, {
keepOriginalNames: true
})
.state('components.button', {
url: '/button',
templateUrl: '../components/button/button.html'
}) .state('components.checkbox', {
url: '/checkbox',
templateUrl: '../components/checkbox/checkbox.html'
})
.state('components.forms', {
url: '/forms',
deepStateRedirect: true,
sticky: true,
views: {
'': { templateUrl: '..forms.html' },
'inline#components.forms': {
templateUrl: '../components/forms/form-inline/forminline.html'
},
'default#components.forms': {
templateUrl: '../components/forms/form-default/formdefault.html'
},
'multicolumn#components.forms': {
templateUrl: '../components/forms/form-multicolumn/formmulticolumn.html'
}
}
});
// use the HTML5 History API
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
});
mendouiApp.controller('componentsController', ['$scope', '$state', 'sideNavService', function($scope, $state, sideNavService, COMPONENTS_LIST){
$scope.componentsList = sideNavService.components;
$scope.componentsnav = COMPONENTS_LIST.children;
$scope.go = function(tab) {
$state.go(tab.name);
}
}]);
mendouiApp.controller('getStartedController', ['$scope', '$state', 'sideNavService', 'fixedSideNavService', function($scope, $state, sideNavService, fixedSideNavService ){
$scope.getstartedList = sideNavService.getstarted;
}]);
/*** This is for the external url reference ***/
mendouiApp.run(function($rootScope, $state, $stateParams, $window, fixedSideNavService, copyToClipBoardService) {
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams, $state, $stateParams) {
if (toState.external) {
event.preventDefault();
$window.open(toState.url, '_self');
}
});
$rootScope.$on('$viewContentLoaded', function(event){
fixedSideNavService.fixedsidenav();
copyToClipBoardService.copytoclipboard();
});
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
$state.transitionTo('home');
});
})();
service.js
angular.module('mendouiApp').service('sideNavService', function() {
return {
"getstarted" : [
{
"name" : "Overview",
"link" : "home.overview"
}
{
"name" : "Summary",
"link" : "home.overview"
}
],
"components" : [
{
"name" : "Alerts",
"link" :"components.alert"
},
{
"name" : "Button",
"link" :"components.button"
},
{
"name" : "Button Groups",
"link" :"components.buttongroup"
},
{
"name" : "Button Icons",
"link" :"components.buttonicons"
},
{
"name" : "Checkbox",
"link" :"components.checkbox"
},
{
"name" : "Datepicker",
"link" :"components.datepicker"
},
{
"name" : "Forms",
"link" : "components.forms"
}
]
};
});
Your question was a bit messy, but after a while playing with I could understand I made this fiddle: http://jsfiddle.net/canastro/c4kt2myc/2/ I hope it works as you were expecting.
The main thing to focus on here is:
.state("root.components.button", {
url: '/components/button',
views: {
'main#': {
template: `
<div>
<a ui-sref="root.components.button.default">default</a>
<a ui-sref="root.components.button.disabled">disabled</a>
<div ui-view="buttonsContent"></div>
</div>
`
}
}
})
.state("root.components.button.default", {
url: '/components/button/default',
views: {
'buttonsContent#root.components.button': {
template: 'root.components.button.default'
}
}
})
.state("root.components.button.disabled", {
url: '/components/button/disabled',
views: {
'buttonsContent#root.components.button': {
template: 'root.components.button.disabled'
}
}
})
In the first level you have a abstract route so you can always have your basic layout present.
Then in the Started / Components routes, you load content into the main and side ui-views.
In all of the Started and Component child routes you just override the main views.
And finally, in the last level you need to say you want to fill the content of a ui-view created in the previous state, by doing something like VIEWNAME#STATENAME.

nested ui-router $location binding

I have some problem with binding when i use ui-router. I am trying to make the app modular and keep it clean and simple.
I have the following app.js
// main routing - index.html
var app = angular.module('mainApp', ['ui.router']);
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('index', {
url: '/',
templateUrl: 'pages/main.html'
})
.state('cars', {
url: '/cars',
templateUrl: 'pages/Cars_model/main.html'
})
.state('cars.audi', {
url: '/audi',
templateUrl: 'pages/Cars_model/audi.html'
})
.state('cars.ford', {
url: '/ford',
templateUrl: 'pages/Cars_model/ford.html'
})
});
app.controller('indexController', function($scope, $location) {
$scope.isIndexPage = function() {
return $location.path() === '/';
}
});
app.controller('carsCtrl', function($scope, $location) {
if($location.path() === '/cars/audi')
{
$scope.pageHeader = "AUDI";
$scope.curentMenu = "Best Cars";
$scope.title = "Audi Specs";
}
if($location.path() === '/cars/ford')
{
$scope.pageHeader = "FORD";
$scope.curentMenu = "Best Cars";
$scope.title = "Ford Specs";
}
});
and the file where i want to use binding
<div class="container" ng-controller="carsCtrl">
<div class="page-header">
<h1>{{pageHeader}}</h1>
</div>
<!-- The first row -->
<div class="row">
<div class="col-lg-12 col-md-12 col-sd-12">
<ol class="breadcrumb">
<li>Home</li>
<li>{{curentMenu}}</li>
<li class="active">{{pageHeader}}</li>
</ol>
</div>
</div>
</div>
The problem is when i load the page the binding work only once, for the second i have to refresh the page.
I am not sure if i used the corect logic
if($location.path() === '/cars/ford')
I think i found the solution
Using
ui-sref-opts="{reload: true}"
in the menu solve the problem
<a ui-sref="cars.audi" ui-sref-opts="{reload: true}">Audi</a>
Plunker

why angularjs controller loading twice

Here is my route config, I am using routeProvider to bind controller to view and not declaring ng-controller in my view still my controller loading twice, I searched for lot of solutions and tried every thing but no use.
$routeProvider.when("/home", {
controller: "homeController",
templateUrl: "app/views/home.html"
}).when("/login", {
controller: "loginController",
templateUrl: "app/views/login.html"
}).when("/regcars", {
controller: "RegCarsController",
templateUrl: "app/views/client/RegCars.html"
}).otherwise({ redirectTo: "/home/" });
Here is template(view)
<div class="col-md-6 box box-success pull-left">
<div class="box-header with-border">
<h3 class="box-title">My cars</h3>
<div class="box-tools pull-right">
<button class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
</div>
</div>
<div class="box-body">
{{CarName}}
</div>
</div>
And here is my controller
app.controller('RegCarsController', function ($scope) {
$scope.CarName = "MyCar";
alert('MyCar');
});
In my above code showing alert twice. Below I have link to call the view, tried with and with out slash at end of href link
<a href="#/regcars/">
<i class="fa fa-car fa-2x"></i> <span>My Cars</span>
</a>
Some proof of concept that controller is called many times. Strange.
On the other hand - the same code on JSFiddle - shows that controller is executed / fired only once.
angular.module('app', ['ngRoute']).config(function($routeProvider) {
$routeProvider.when("/home", {
controller: "homeController",
templateUrl: "app/views/home.html"
}).when("/regcars", {
controller: "RegCarsController",
templateUrl: "app/views/client/RegCars.html"
}).otherwise({ redirectTo: "/home" });
})
.run(function($templateCache) {
$templateCache.put('app/views/home.html', '<div>home tempalte</div>');
$templateCache.put('app/views/client/RegCars.html', '<div>cars template, car name: {{ CarName }}</div>');
})
.controller('homeController', function() {})
.controller('RegCarsController', function($scope) {
$scope.CarName = "MyCar";
console.log('Called many times')
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-route.min.js"></script>
<div ng-app='app'>
<ul><li><a href='#/'>Home</a></li><li><a href='#/regcars'>Cars</a></li></ul>
<ng-view></ng-view>
</div>

Checkout Step Navigation

i have no idea how to solve this Problem.
I have 4 Checkout Steps. Each Step has an Form to fullfill.
If Form is valid, the next Step in Navigation should be activated.
This is the Routing Script
"use strict";
var router = angular.module("router", ["ui.router"]);
router.config(["$stateProvider", "$urlRouterProvider", "$locationProvider", "$httpProvider",
function($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: true,
rewriteLinks: true
});
$stateProvider
.state("step1", {
url: "/step1",
controller: "Step1Controller",
templateUrl: "app/views/step1-partial.html"
})
.state("step2", {
url: "/step2",
controller: "Step2Controller",
templateUrl: "app/views/step2-partial.html"
})
.state("step3", {
url: "/step3",
controller: "Step3Controller",
templateUrl: "app/views/step3-partial.html"
})
.state("step4", {
url: "/step4",
controller: "Step4Controller",
templateUrl: "app/views/step4-partial.html"
});
$urlRouterProvider.otherwise("/step1");
}
]);
router.run(function($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
});
and this is one of the Partials View
<section class="steps">
<ul class="clear-list">
<li class="active">Step1</li>
<li>Step2</i></li>
<li>Step3</li>
<li>Step4</li>
</ul>
</section>
<form name="registerForm" ng-cloak>
formfields...
</form>
<div class="step-footer">
Next >
</div>
can somebody help me out
In processData() function (which i am hoping you will we having in all three controllers) after successful processing of data you can do $location.path('/step2');
and so on for all the steps.
For activating the current section in which currently you are, you can have some common variable in all three controller and set the value of that variable like ($scope.currentStep = step1) respectively.
Example.
<section class="steps">
<ul class="clear-list">
<li ng-class="{active : currentStep=='step1'}">Step1</li>
<li ng-class="{active : currentStep=='step2'}">Step2</i></li>
<li ng-class="{active : currentStep=='step3'}">Step3</li>
<li ng-class="{active : currentStep=='step4'}">Step4</li>
</ul>
</section>
use ui-sref-active="active" instead of class

Undefined Controller AngularJS

My template is loading but I get an error that the controller is undefined. The controller does exist in my sources exactly at the location defined. What is wrong with this code?
Error: [ng:areq] Argument '/Scripts/controllers/wizardNavigationCtrl.js' is not a function, got undefined
http://errors.angularjs.org/1.2.14/ng/areq?p0=%2FScripts%2Fcontrollers%2FwizardNavigationCtrl.js&p1=not%20aNaNunction%2C%20got%20undefined
Index.html (root page)
<div class="container">
<div ui-view></div>
</div>
wizardLayout.html
<div>
<ul class="nav nav-tabs">
<li ng-repeat="model in models" ng-class="active: model.active">
<a ui-sref=".model-{{model.name}}">model.name</a>
</li>
<li ng-class="navStep=='addnew' ? 'active' : ''">
<a ui-sref=".newmodel"><span class="glyphicon glyphicon-plus"></span></a>
</li>
<li><a ui-sref=".other">Other</a></li>
<li><a ui-sref=".customer">Customer Info</a></li>
<li><a ui-sref=".shipping">Shipping Info</a></li>
<li><a ui-sref=".review">Review</a></li>
</ul>
</div>
<div ui-view>
</div>
app.js:
'use strict';
var myApp = angular.module('myApp', ['ui.router']);
myApp.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('wizard', {
url: '/',
templateUrl: 'Scripts/templates/wizardLayout.html',
controller: 'Scripts/controllers/wizardNavigationCtrl.js'
})
.state('wizard.newmodel', {
url: '/newmodel',
templateUrl: 'Scripts/templates/wizardModel.html',
controller: 'Scripts/controllers/wizardModelCtrl.js'
})
.state('wizard.other', {
url: '/other',
templateUrl: 'Scripts/templates/wizardOther.html',
controller: 'Scripts/controllers/wizardOtherCtrl.js'
})
.state('wizard.customer', {
url: '/customer',
templateUrl: 'Scripts/templates/wizardCustomer.html',
controller: 'Scripts/controllers/wizardCustomerCtrl.js'
})
.state('wizard.shipping', {
url: '/shipping',
templateUrl: 'Scripts/templates/wizardShipping.html',
controller: 'Scripts/controllers/wizardShippingCtrl.js'
})
.state('wizard.review', {
url: '/review',
templateUrl: 'Scripts/templates/wizardReview.html',
controller: 'Scripts/controllers/wizardReviewCtrl.js'
});
}]);
wizardNavigationCtrl.js
myApp.controller('wizardNavigationCtrl', ['wizardSvc', '$scope', function (wizardSvc, $scope) {
alert('navigation controller! ' + wizardSvc.quote.title);
$scope.navStep = 'addnew';
wizardSvc.init();
}])
The controller should be in the format MyControllerName not the name and path to the javascript file. That in mind, in order to use the controller the javascript must have been loaded by the browser already. This requires the use of a traditional script tag because angular won't find or load these scripts for you.
Taking a snippet from your code it becomes:
.state('wizard', {
url: '/',
templateUrl: 'Scripts/templates/wizardLayout.html',
controller: 'wizardNavigationCtrl'
})
And somewhere in the page you need:
<script src="Scripts/controllers/wizardNavigationCtrl.js" type="text/javascript"></script>
Hope that helps!

Resources