I'm trying to lazy load a directive in my angular app, using ui.router and oc.lazyLoad. Here is my code :
menu :
<ul>
<li><a ui-sref="home">Home</a></li>
<li><a ui-sref="demo">Demo</a></li>
<li><a ui-sref="test">Test</a></li>
</ul>
<ui-view></ui-view>
route config :
angular.module('app', ['ui.router', 'oc.lazyLoad'])
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider
.state("demo", {
url:'/demo',
views: {
'lazyLoadView' : {
template: '<demo-directive></demo-directive>'
}
},
resolve : {
loadDemoModule : ['$ocLazyLoad', function($ocLazyLoad) {
console.log('resolving demo lazy load');
return $ocLazyLoad.load('demo.js');
}]
}
})
.state("home", {
templateUrl : 'core/home.html',
url : '/home'
})
}])
and the directive :
angular.module('app').
directive('demoDirective', function() {
return {
restrict: 'E',
scope: {},
template: require('./demo-directive.html'),
// templateUrl: 'demo-directive.html',
controllerAs: 'demo',
controller : ['$timeout', function($timeout) {
console.log('in directive controller');
}]
};
});
I have no errors, the console.log in resolve function is displayed, the demo.js file is loaded but then noting is happening, console form directive controller is not displayed. I'm trying to follow the first example from ocLazyLoad example
Thanks
How about lazy loading this way.
return $ocLazyLoad.load({
name: 'app.demo',
files: ['path/to/demo.js']
})
You have not declared the oc.lazyLoad module as a dependency.
angular.module('app.demo', ["oc.lazyLoad"])
See the quickstart - https://oclazyload.readme.io/docs/
You're also not closing your demo directive
template: '<demo-directive></demo-directive>'
Related
'use strict';
angular.module('confusionApp', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
// route for the home page
.state('app', {
url:'/',
views: {
'header': {
templateUrl : 'views/header.html'
},
'content': {
template : '<h1>To be Completed</h1>',
controller : 'IndexController'
},
'footer': {
templateUrl : 'views/footer.html'
}
}
})
// route for the aboutus page
.state('app.aboutus', {
url:'aboutus',
views: {
'content#': {
template: '<h1>To be Completed</h1>'
}
}
})
// route for the contactus page
.state('app.contactus', {
url:'contactus',
views: {
'content#': {
templateUrl : 'views/contactus.html',
controller : 'ContactController'
}
}
})
// route for the menu page
.state('app.menu', {
url: 'menu',
views: {
'content#': {
templateUrl : 'views/menu.html',
controller : 'MenuController'
}
}
})
// route for the dishdetail page
.state('app.dishdetails', {
url: 'menu/:id',
views: {
'content#': {
templateUrl : 'views/dishdetail.html',
controller : 'DishDetailController'
}
}
});
$urlRouterProvider.otherwise('/');
});
For the app.js file I am trying to use the UI-Router, I used bower to install the the angular dependencies for the UI-Router. They currently have the right path when I include them in the tags. I checked to make sure that the files were also there inside of the bower_components file. Yet when I run the program nothing shows up and the only error that I recieve is the "Uncaught Error: [$injector:modulerr]" error.
It's seem like angular can't find ui-route module,
remember include it in your html. Use something like that
<script src="/bower_components/angular/angular.js"></script>
<script src="/bower_components/angular-ui-router/angular-ui-router.js"></script>
if you are using bower.
Sorry by my english. I hope this will be useful for you.
I had similar issue. What fixed it was to inject '$stateProvider' and '$urlRouterProvider' before using them in the config function such as:
angular.module('confusionApp', ['ui.router'])
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider
// .. and so on
}]);
Try load ui.router before you load a script:
<!-- UI-Router -->
<script src="angular-ui-router.js"></script>
<script src="yourscript.js"></script>
So I am using ui-view to route me to a partial.
//route.provider.js
(function() {
'use strict';
angular
.module('app')
.provider('RouteService', RouteService);
RouteService.$inject = ['$stateProvider', '$urlRouterProvider'];
function RouteService ($stateProvider, $urlRouterProvider) {
var service = {};
this.$get = function() { return service; };
this.initialize = function() {
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('home', {
url: '/home',
controller: 'HomeController',
templateUrl: 'home/home.view.html',
controllerAs: 'viewModel'
})
.state('login', {
url: '/login',
controller: 'LoginController',
templateUrl: 'login/login.view.html',
controllerAs: 'viewModel'
})
//TODO Impliment the following partial pages...
.state('gensim', {
url: '/gensim',
templateUrl: 'general-simulation/simulation.view.html',
controller: 'TabsController',
controllerAs: 'tabs'
})
<...more routes...>
}
}
})();
The issue I am having is once it routes to
// general-simulation/simulation.view.html
I'd like it to use a custom directive to insert more html into the page.
Inside simulation.view.html I have this.
<div class="container">
<div class="row center">
<div class="col-xs-12">
<h1>General Simulation</h1>
<gs-tabs><h1>TEST!!!!</h1></gs-tabs>
</div>
</div>
</div>
The directive is constructed in
// tabs.directives.js
(function(){
'use strict';
angular
.module('app')
.directive('gsTabs', gsTabs);
function gsTabs () {
return {
restrict: "E",
templateURL: 'tabs.view.html'
};
}
})();
Finally, my tabs.view.html looks like this.
<h1>YOU HAVE ENTERED TABS PARTIAL</h1>
When I navigate to the page that displays simulation.view all I can see is:
General Simulation
TEST!!!!
So what am I doing wrong here. I checked for camelCasing and the page is not showing in errors. Any help would be greatly appreciated!
Update:
I viewed the network calls in chrome's dev tools.
simulation.view.html is being loaded but tabs.view.html isn't.
Request URL:http://sdc-stagt01/AngularJS/general-simulation/simulation.view.html
Request Method:GET
Status Code:200 OK
Remote Address:10.19.8.96:80
The file substructure is:
/general-simulation/tabs/tabs.controller.js
/general-simulation/tabs/tabs.directives.js
/general-simulation/tabs/tabs.view.html
/general-simulation/simulation.view.html
putting comment as answer
change templateURL to templateUrl
So entre's comment was a big help. That got chrome dev to start spitting out errors.
charlietfl Was on the right track with mentioning my file structure as well. I needed to change my directive to look like this:
templateUrl: 'general-simulation/tabs/tabs.view.html'
Thank you!
You have a typo here. templateUrl not templateURL
function gsTabs () {
return {
restrict: "E",
templateURL: 'tabs.view.html' // change this to templateUrl
};
}
I am having an issue where once the templateUrl is added into the ui-router child state, the application will no longer perform the routing to the state. It works fine when it's just a template.
app.js:
app.config(['$stateProvider', '$locationProvider', '$urlMatcherFactoryProvider', '$urlRouterProvider',
function ($stateProvider, $locationProvider, $urlMatcherFactoryProvider, $urlRouterProvider) {
$urlMatcherFactoryProvider.caseInsensitive(true);
$urlMatcherFactoryProvider.strictMode(false);
$urlRouterProvider.otherwise('/page-not-found');
$stateProvider
.state('dashboard', {
url: '/',
views: {
'header': {
template: 'header'
},
'nav': {
template: 'nav'
},
main: {
template: 'You are on the homepage'
}
}
});
$locationProvider.html5Mode(true);
}]);
app.run(['$rootScope', 'userService', '$state', function ($rootScope, user, $state) {
$rootScope.$on("$stateChangeError", console.log.bind(console));
if (!user.exists) {
$state.go('user.reg');
}
}]);
User.states.js:
.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('user', {
url: '/users',
abstract: true,
views: {
'header': {},
'nav': {},
'main': {
template: '<ui-view/>'
}
}
})
.state('user.reg', {
url: '/register',
//template: 'This will show fine',
templateUrl: '/app/Users/User.login.html' // this will break
});
}]);
UPDATE
If I add a ui-sref="user.reg" to my initial pages I can navigate to the state/page fine, with the templateUrl and template . So its just an issue when I try to use state.go('user.reg');
This means a work around is using the $location provider to change the path. Has the same effect but does seem rather wrong
The problem is with your relative paths.
Look at this code:
$locationProvider.html5Mode(true);
You have html5 mode enabled, and for that to work, you have your base ref set in your html, which probably looks like this:
<base href="/">
Your issue is likely that the route for your template isn't "yoursite.com/app/Users/User.login.html."
See this Plunker for a working version of your code. Then go into the html code and uncomment out the base tag, and notice that it will break.
I have a LanguageSwitcher service and a LanguageSwitcher.switchLanguage() function that I can use to switch Language between french and english.
I am now trying to use a ui-router state to execute that function and it seems to work because I can see a 'translated' class (it toggles between 'french' and 'english') change in the markup when inspecting BUT the page goes blank like it's trying to load a view that is not there or something.
So I would like to prevent this behaviour and simply execute the function 'without changing the state' if possible.
<a ui-sref="language">Toggle</a>
Here is the ui-router config:
'use strict';
(function() {
angular.module('frontApp')
.run(['$rootScope', '$state', '$stateParams', function($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
}]
)
.config(['$urlRouterProvider', '$stateProvider', '$locationProvider', function($urlRouterProvider, $stateProvider, $locationProvider){
$urlRouterProvider
.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: '/views/home.html',
controller: 'HomeCtrl'
})
.state('home.rules', {
url: '^/rules',
templateUrl: '/views/rules.html'
})
.state('home.terms', {
url: '^/terms',
templateUrl: '/views/terms.html'
})
.state('home.faq', {
url: '^/faq',
templateUrl: '/views/faq.html'
})
.state('language', {
controller: ['LanguageSwitcher', function(LanguageSwitcher) {
LanguageSwitcher.switchLanguage();
}]
});
$locationProvider.html5Mode(true);
}]);
}());
This is because my menu is dynamic and the toggle is not the last item of the navbar:
<header ng-controller="NavbarCtrl">
<h1><a class="navbar-brand" ui-sref="home">{{ 'siteTitle' | translate }}</a></h1>
<ul class="nav navbar-nav navbar-right">
<li ng-repeat="item in menu" ui-sref-active="active">
<a ui-sref="{{item.state}}" ng-href="{{item.link}}">{{item.title}}</a>
</li>
</ul>
</header>
The navbar.js file:
'use strict';
(function() {
angular.module('frontApp').controller('NavbarCtrl', ['$scope', '$translate', '$location', '$rootScope', function ($scope, $translate, $location, $rootScope) {
$rootScope.$on('$translateChangeSuccess', function () {
$translate(['linkHome', 'linkRules', 'linkTerms', 'linkFAQ', 'language', 'otherLanguage', 'linkMainSite']).then(function (translations) {
$scope.menu = [
{
'title': translations.linkHome,
'link': '/',
'state': 'home'
},
{
'title': translations.linkRules,
'link': '/rules',
'state': 'home.rules'
},
{
'title': translations.linkTerms,
'link': '/terms',
'state': 'home.terms'
},
{
'title': translations.linkFAQ,
'link': '/faq',
'state': 'home.faq'
},
{
'title': translations.language,
'link': '/'+translations.otherLanguage,
'state': 'language'
},
//{
// 'title': translations.linkMainSite,
// 'link': 'http://'+translations.linkMainSite,
// 'state': ''
//}
];
//$scope.isActive = function(route) {
// return route === $location.path();
//};
});
});
}]);
}());
What I am missing? Many thanks for your time and help.
Based on the problem being how to use ng-repeat for the menu links, one suggestion would be using ng-if to create a different link for language that uses ng-click to manage the switching and not set any href attributes for it
Something like
<li ng-repeat="item in menu" ui-sref-active="active">
<a ng-if="item.state !== 'language'" ui-sref="{{item.state}}" ng-href="{{item.link}}">{{item.title}}</a>
<a ng-if="item.state === 'language'" ng-click="switchLang()">{{item.title}}</a>
</li>
Then in NavbarCtrl controller have switchLang() make the call to your language service
This is inferred in many of the comments from your post: there is no reason to use a state to call the language switcher.
Instead you probably just want to include the controller in your menu using ng-controller, or create a component/directive, and call the service method through the using ngClick.
I am using angular-ui-router module of AngularJS and have the following ui-sref which when I hover over shows http://localhost:3000/u/bob#/123/pin/4567, but when I click on it, I get only http://localhost:3000/u/bob#/123/pin/ on the browser's URL address bar and get the parameter value 4567 lost.
HTML code (index.html):
<a ui-sref="users.maker">
<!-- stuff -->
</a>
JavaScript code:
.state('users', {
url: '/:foo',
views: {
'': {
templateUrl: '/partials/index.html',
controller: ['$rootScope', '$stateParams',
function($rootScope, $stateParams) {
//stuff
}]
}
}
})
.state('users.maker', {
url: '/pin/:bar',
templateUrl: '/partials/users.maker.html',
controller: ['$stateParams', '$scope', '$http',
function($stateParams, $scope, ) {
//stuff
}]
})
Could somebody help me with it?
Have you tried defining your ui-sref as following?
ui-sref="users.maker({ param })
Dynamic ui-sref do not work in ui-router. A function using $state.href() could be used to resolve this issue.
So <a ui-sref="users.maker({ foo: bar })">...</a> could be done by following:
HTML
<a href="{{goToState('users.maker', bar)}}">..<a>
Inside AngularJS Controller
$scope.goToState = function(state, param) {
return $state.href(state, {foo: param});
}
This is with angular-ui-router version 0.2.10.
For more:
https://github.com/angular-ui/ui-router/issues/395