I load the angular views by ui-router
...
.state('app.page.search', {
url: '/search',
templateUrl: 'tpl/page_search.html'
})
I ran into XXX is not a function randomly,
How could I make sure the external files are loaded after Angular views are ready?
tpl/root_layout.html
<div data-ng-include="'tpl/header.html'"></div>
<div class="content-container no-padding">
<div class="container-full">
<!-- <div data-ng-include="'tpl/search.html'"></div> -->
<div class="app-content-body fade-in-up" ui-view></div>
</div>
</div>
<div data-ng-include="'tpl/footer.html'"></div>
tpl/page_search.html
<DOM>
....
<DOM>
<script type='text/javascript' src='js/scriptA.js'></script>
<script type='text/javascript' src='js/scriptB.js'></script>
as #Daniel Higueras suggested, use the UI Router's resolve to wait for your assets to load in
.state('state', {
url: '/state',
templateUrl: 'url/state.html',
resolve: {
asset1: function($http) {
return $http.get();
},
asset2: function($http) {
return $http.get();
}
}
}
if you want to load your assets after everything's done, you can use the ocLazyLoad service: https://oclazyload.readme.io/docs/oclazyload-service
Just use it in your controller:
app.controller('ctrl', function($ocLazyLoad) {
$ocLazyLoad.load('asset1.js').then(
function(res) {
// asset 1 is available
}
);
$ocLazyLoad.load('asset2.js').then(
function(res) {
// asset 2 is available
}
);
});
this is helpful when you have large a large asset like D3 where only one page of your app uses it, so you don't want to pull it in every time your app loads.
Related
I am experiencing a problem when trying to test my portfolio website on my mother’s mobile (Samsung Galaxy JS 3). The images and titles of the projects get loaded onto the index page from JSON with ng-repeat and the links to the information are made from the project IDs with ui-sref. The website loads on the mobile all right and it can direct to the about page, which also uses ui-sref, but it cannot direct to the child pages – it either stays on the main page, or if I force it to go to one of the pages, it displays a blank page with a toggle menu (ng-include header).
It works fine on a Sony Xperia M4, Samsung Galaxy Young, Galaxy A5, my desktop computer (Windows 8.1) and a Mac (not sure about the operating system). I’ve followed the “Hello Solarsystem” tutorial, which also seems to have the same issue when I tried the Plunker version of it on her phone this morning (7th of June).
I have ensured that the site was using the most up to date version after reading ui-sref not working in nested views, I’ve tried adding ui-view to the template that displays the project’s links as is advised on here: Ui-sref not generating clickable links/not working and I am now feeling stuck.
Sorry if my question is a bit long, but I've never had to write one before and I don't want to miss anything.
EDIT: I have now made a plunk with the exact code I'm using for the projects - Plunker and I have now removed ui-router, so it does not load the inner page as a sub page, but at least is viewable in all browsers - the plunk is using ui-router.
The code that I'm thinking has issues is being listed below.
projects.html - view
<div class="container">
<div class="wrapper">
<div class="col-xs-12 col-sm-6 col-md-4 project-block" ng-repeat="project in $ctrl.projects">
<a ui-sref="project({ projectId: project.id })" ui-sref-active="active">
<div class="grid-item university">
<div class="grid-caption">
<img ng-src="{{project.thumb}}" alt="{{project.name}} ({{project.desc}})" id="portfolio-thumb-{{project.id}}" />
<div class="titles">
<div class="grid-projects title">{{project.name}}</div>
<div class="grid-projects desc">{{project.desc}}</div>
</div>
</div>
</div>
</a>
</div>
</div>
</div>
<ui-view></ui-view>
index.html
<body ng-app="myPortfolio">
<div id="wrapper">
<header ng-include="'header.html'"></header>
<div id="page-content-wrapper">
Toggle Menu
<ui-view></ui-view>
<uir-state-vis class="statevis" width="300" height="100"></uir-state-vis>
</div>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
</div>
</body>
app.js
var myApp = angular.module('myPortfolio', ['ui.router', 'slick', 'ngAnimate', 'ngRoute', 'ngResource', 'ngTouch', 'ngSanitize', 'ui.bootstrap']);
myApp.config(function ($stateProvider) {
// An array of state definitions
var states = [
{
name: 'about',
url: '/about',
component: 'about'
},
{
name: 'projects',
url: '/projects',
component: 'projects',
// It delegates to the ProjectService to HTTP fetch (async)
// The project component receives this via its `bindings: `
resolve: {
projects: function (ProjectService) {
return ProjectService.getAllProjects();
}
}
},
{
name: 'project',
// This state takes a URL parameter called projectId
url: '/project/{projectId}',
component: 'project',
// This state defines a 'project' resolve
// It delegates to the ProjectService, passing the projectId parameter
resolve: {
project: function (ProjectService, $transition$) {
return ProjectService.getProject($transition$.params().projectId);
}
}
}
]
// Loop over the state definitions and register them
states.forEach(function (state) {
$stateProvider.state(state);
});
});
myApp.config(function ($urlRouterProvider) {
// when there is an empty route, redirect to /index
$urlRouterProvider.when('', '/projects');
});
// preload the async data
myApp.run(function ($http) {
$http.get('data/projects.json', { cache: true });
$http.get('data/info.json', { cache: true });
});
//Make html in JSON file trusted
myApp.filter('to_trusted', ['$sce', function ($sce) {
return function (text) {
return $sce.trustAsHtml(text);
};
}]);
projects.js - component
angular.module('myPortfolio').service('ProjectService', function($http) {
var service = {
getAllProjects: function() {
return $http.get('data/projects.json', { cache: true }).then(function(resp) {
return resp.data;
});
},
getProject: function(id) {
function projectMatchesParam(project) {
return project.id === id;
}
return service.getAllProjects().then(function (projects) {
return projects.find(projectMatchesParam)
});
}
}
return service;
})
projects.js - service
angular.module('myPortfolio').service('ProjectService', function($http) {
var service = {
getAllProjects: function() {
return $http.get('data/projects.json', { cache: true }).then(function(resp) {
return resp.data;
});
},
getProject: function(id) {
function projectMatchesParam(project) {
return project.id === id;
}
return service.getAllProjects().then(function (projects) {
return projects.find(projectMatchesParam)
});
}
}
return service;
})
I have multiple views on one page and within one view I have nested view.How should I configure this in app.js.Given below is my code which is not working.
This is my index.html file
<body ng-app="configuratorApp" >
<div ui-view="view1"></div>
<div ui-view="view2"></div>
</body>
This is my view1.html file
<div ui-view> </div>
<button type="button" ui-sref="view1.child1"></button>
<button type="button" ui-sref="view1.child2"></button>
This is my view1-child1.html file
<h1>Child1<h1>
This is my view1-child2.html file
<h1>Child2<h1>
This is my view2.html file
<h1>Hello World</h1>
This is my app.js file
.state('home',{
url: '/',
views: {
'': {
templateUrl: 'index.html'
},
'view1#home': {
templateUrl: 'view1.html'
},'view2#home': {
templateUrl: 'view2.html'
}
}
})
.state('view1.child1', {
url: '/child1',
templateUrl: 'view1-child1.html'
})
.state('view1.child2', {
url: '/child2',
templateUrl: 'view1-child2.html'
})
You confused the views with the states.
There is no view1.child1 state, reason being you do not have a view1 as a parent state (unless the code you posted above is incomplete). The name should be home.child instead.
.state('home.child1', { //this should be home.child1 instead of view1.child1
url: '/child1',
templateUrl: 'view1-child1.html'
})
.state('home.child2', {
url: '/child2',
templateUrl: 'view1-child2.html'
})
Also bear in mind that you will need a root template (or unnamed root template) in your index.html, else your homestate cannot be populated.
So in your index.html, you need to have this:
<body ng-app="configuratorApp">
<div ui-view></div> <!--this is the root template, to let Home state 'live' here-->
</body>
Here is the working plnkr
P.s. if the plnkr is not working just refresh it. sometimes it has problem fetching the htmls
I'm trying to integrate angularjs to an existing site.
The problem is that I've transformed a section of the main page into an angular view but when this latter is loaded into the main page using ng-route the main page slider scripts that are located at the bottom of the main page do not seem to render in the loaded view.
Does anyone have an idea how to get through this.
Thanks.
</div>
</header>
<div data-ng-view></div>
<footer id="footer">
<div class="container">
(function() {
var app = angular.module('hbcm', ['ngRoute']);
angular.module('hbcm').controller('DsplController', function() {
this.panel = 1;
});
app.config(function($routeProvider) {
$routeProvider
.when('/', {
controller: 'DsplController',
templateUrl: 'view1.html'
})
.when('/about-us/', {
templateUrl: 'about-us.html'
})
.otherwise({
redirectTo: '/'
});
});
})();
create a controller to handle you template (View), and attach that controller in the Route configuration
$routeProvider.when('/somewhere', { controller: TheNameOfYourController, });
i am trying to route in angular.js (1.3.15)and getting these two errors :
error messages
1-WARNING: Tried to load angular more than once.
2-angular.js:38Uncaught Error: [$injector:modulerr]
http://errors.angularjs.org/1.3.15/$injector/modulerr?p0=after_login&
p1=Err…0d%20(http%3A%2F
%2Flocalhost%3A49062%2FScripts%2Fangular.min.js%3A17%3A381)
my module.js
var after_login = angular.module("after_login", ['ngRoute', 'CrackWeb']);
after_login.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/groups',
{
templateUrl: 'Views/p1.cshtml',
controller: 'MyScripts/groups'
})
.otherwise(
{
redirectTo: '/'
});
$locationProvider.html5Mode(true).hashPrefix('!');
}]);
in my html page with ng-app i have written.
p1.cshtml [ partial ]
<div class="col-md-9">
<br />
<input ng-model="check" id="ch"/>
{{check}}
<div ng-view></div>
</div>
Can anyone help ?
In your route provider you have mentioned
$routeProvider.when('/groups',
{
templateUrl: 'Views/p1.cshtml',
controller: 'MyScripts/groups'
})
.otherwise(
{
redirectTo: '/'
});
but you dont have default route
$routeProvider.when('/',
{
templateUrl: 'sometemplate',
controller: 'somecontroller'
});
so it will try to load your default HTML(most cases index.html) again and again and it cause the error
You can not load a page with cshtml extension!
Actually you are wrong when you try to load the page CSHTML through the ANGULAR ROUTING.
As you can not load this page alone so well you can not load it through ANGULAR route.
So if you want to load a page CSHTML then you have to call his controller in MVC
and to load it via 'ActionResult'.
I Need to load two html files in a base html file .In other words I have base html file in which I have header and contend view .I need to load different HTML file in header and in contend view ..
Here is Base HTML file
<div class="container">
<div class="row page-header">
<ui-view name="header"></ui-view>
</div>
<ui-view name="content"></ui-view>
<div class="row">
<div class="col-xs-12">
<hr>
<p class="text-center">Test Come</p>
</div>
</div>
</div>
In this view
<ui-view name="header"></ui-view>
in header I need to load header.html and <ui-view name="content"></ui-view> in thisI need to load content.html
http://plnkr.co/edit/nMhlb0R1q3BhWBHEjCks?p=preview
Thanks
You need to update your state according to child states:
var config = function($stateProvider,$urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('main', {
url: '/',
views: {
// the main template will be placed here (relatively named)
'': { templateUrl: 'base.html' },
// the child views will be defined here (absolutely named)
'content#main': { template: 'contend.html' },
// for column two, we'll define a separate controller
'header#main': {
templateUrl: 'header.html',
}
}
});
};
You can have just one ng-view.
You can change its content in several ways: ng-include, ng-switch or mapping different controllers and templates through the routeProvider.
UI-Router is a project that may help: https://github.com/angular-ui/ui-router One of it's features is Multiple Parallel Views
EDIT
Checkout this plnkr
There were some problem with your code
(1) inject $stateProvider instead of $routeProvider if you are uing ui-router
(2) use ui-view instead of ng-view
(3) you can have multiple view at same template level. If you tries to define ui-view inside ui-view and you create multiple ui-view in single state, it will not work.
(4) ui-view inside ui-view will create another state.
var app=angular.module("firstApp",['ui.router']);
var config = function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state('base', {
url: "/",
views: {
"content": { templateUrl: "contend.html" },
"header": { templateUrl: "header.html" }
}
})
};
config.$inject = ['$stateProvider', '$urlRouterProvider'];
var loginCntrl=function($scope){
}
loginCntrl.$inject=['$scope']
app.config(config);
app.controller(loginCntrl);