I am unable to get ui.router to load a component on index.html, through a localhost or otherwise:
index.html
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="//unpkg.com/angular-ui-router#0.3.1/release/angular-ui-router.js"></script> <!-- used to route views -->
<script src="js/components.js"></script>
<body ng-app="myApp">
<div> <!-- main content -->
<ui-view></ui-view> <!-- this directs ui-router to put the home view here-->
</div>
components.js
var app = angular.module('myApp', ['ui.router']); //makes a call to the Angular API to create our app, configured with the ui.router plug-in
//configure our view router
app.config(function($stateProvider) {
//create our different views as objects
var mainState ={
name: 'main', //name of the object
url: '', //url to point to, or that causes this view to be triggered
component: 'home', //component that works with the data, loads the template
resolve: { //data to bind to our component
data: function(Resource) {
console.log(Resource.test()) //returns "Hello World"
return Resource.test()
}
}
}
//call the states
$stateProvider.state(mainState);
})
app.service('Resource', function ($http) {
var service = {
test: function() {
return "Hello world"
}
}
return service;
})
app.component('home', {
bindings: { data: '<'}, //make the data we loaded into the view from the factory available to this component
template: "<p>{{data}}</p>", //this is the html that we will plug our data into
controller: function () {
console.log(this) //does not call
}
})
"Hello world" loads, as does data when I make $http gets through the service. But it does not get passed to the component. Any thoughts?
component attribute is available from ui-router#1.0.0(see here and in CHANGELOG.MD - it was added in 1.0.0-aplpha) so it's not available 0.3.1.
Here is working jsFiddle (with 1.0.3-beta)
By default the data will be applicable on view with $ctrl controller alias
template: "<p>{{$ctrl.data}}</p>",
Demo Plunkr
Related
So I am having trouble loading my custom CreateBooking.html which only has this as a test
<div class="container">
<h2>AngularJS Test</h2></div>
My structure is like this
The main angular module
module Asda {
var app = angular.module("BookingApp", ["ngRoute"])
.config(function ($routeProvider: ng.route.IRouteProvider, $locationProvider: ng.ILocationProvider) {
$locationProvider.html5Mode(true);
});
}
The controller
module Asda {
export class CreateBookingController {
static $inject = ["$scope", "$http"];
bookingData: IBookingViewModel;
constructor($scope, $http) {
this.bookingData.Action = "Test";
}
static routing($routeProvider) {
$routeProvider.when("/createbooking",
{
controller: "CreateBookingController",
templateUrl: "/app/CreateBooking/CreateBooking.html",
controllerAs: "ctr"
});
}
}
angular.module("BookingApp")
.controller("CreateBookingController", CreateBookingController)
.config(["$routeProvider", CreateBookingController.routing]);
};
As I am using .net core MVC I am catching the request and loading a generic cshtml view which has this inside
<div ng-view>
So angular should be able to load its view... however the html in CreateBooking.html is not rendered..
I have added the files in this order in my head section
<script src="~/js/angular.min.js"></script>
<script src="~/js/angular-route.min.js"></script>
<!-- Main angular app module-->
<script src="~/App/BookingApp.js"></script>
<!-- Angular controllers-->
<script src="~/App/CreateBooking/CreateBookingController.js"></script>
angular and angular-route are both v1.7.9
I am at a loss.. :/
Dont forget to kickstart with ng-app!
code:
<!DOCTYPE html>
<html>
<head>
<title>Ui State Demo</title>
<meta charset="utf-8">
<!--AngularJS v1.5.9-->
<script type="text/javascript" src="angular.min.js"></script>
<!--angular-ui-router v0.2.15-->
<script type="text/javascript" src="angular-ui-router.min.js"></script>
<script type="text/javascript">
var app = angular.module('uiDemo', ['ui.router']);
app.config(function($stateProvider) {
$stateProvider.state('parent', {
url: '/parent',
controller: 'ParentController'
}).state('childOne', {
controller: 'ChildOneController',
template: '<h1>Child One</h2>'
}).state('childTwo', {
controller: 'ChildTwoController',
template: '<h1>Child Two</h2>'
});
});
app.controller('ParentController', ['$state', function($state) {
console.log('Parent Controller Start');
if (Math.round(Math.random()) == 0) {
$state.go('childOne');
} else {
$state.go('childTwo');
}
}]);
app.controller('ChildOneController', function() {
console.log('Child One');
});
app.controller('ChildTwoController', function() {
console.log('Child Two');
});
</script>
</head>
<body ng-app="uiDemo">
<nav>
<a ui-sref="parent">Parent</a>
</nav>
<ui-view></ui-view>
</body>
</html>
State parent has a url while childOne and childTwo have none. They share same url with parent.
When I click Parent, it will redirect to ChildOneController or ChildTwoController by random, but will also load ParentController twice.
It works fine if I put two different urls on both ChildControllers. But I want to keep the url same as parent after redirected to ChildControllers.
Can someone help? How to avoid this twice loading issue?
But I want to keep the url same as parent after redirected to
ChildControllers. From comment: So I wonder is there a way to avoid
duplicated contoller loading and keep the 'parent' state and
controller?
Option1
You can write for parent state abstract:true so this controller will be loaded once only when state changes from parent.childOne to parent.childTwo
For example:
state('parent',
{
url: '/parent',
abstract:true,
templateUrl: 'parent.html',
controller: 'ParentController'
})
.state('parent.childOne',{ url: '/childOne', templateUrl: 'childOne.html'})
.state('parent.childTwo',{ url: '/childTwo', templateUrl: 'childTwo.html'})
Option 2
You can do some trick to avoid to call controller second time:
At beginning of controller call:
if ($state.transition) return; //hack https://github.com/angular-ui/ui-router/issues/64
Well you could make the parent not a 'state' and just have it as a page controller tied to your nav.
<nav ng-controller="ParentController">
<a ng-click="vm.loadChildState()">Parent</a>
</nav>
Make a method called loadChildState() in the 'parent' controller, which then performs as it does now, using $state.go.
It should still function the same, and clicking on the link will load up the individual child states as you currently have it, without re-loading the Parent Controller.
I am learning Angularjs and having problem with routing. I write up a very simple slim demo example which uses out of the box MVC5. The home page display fine but when I click on the About link it doesn't show the About page and AboutController break point is not hit. And got the following error in Console
Error: [$compile:tpload] Failed to load template: templates/indexView.html (HTTP status: 404 Not Found).
If I swap the two route, then my About page is displayed but got the error when clicking Home link so I am sure the html can be loaded. What do I need to do in order to get the routing to work?
Below is the index.cshtml
#{
ViewBag.Title = "Home Page";
ViewBag.InitModule = "homeIndex";
}
#section Scripts {
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-route.js"></script>
<script src="~/js/home-index.js"></script>
}
<div data-ng-view=""></div>
Below is the About.cshtml
#{
ViewBag.Title = "About Page";
ViewBag.InitModule = "homeIndex";
}
#section Scripts {
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-route.js"></script>
<script src="~/js/home-index.js"></script>
}
<div data-ng-view=""></div>
below is the home-index.js
// home-index.js
var module = angular.module("homeIndex", ["ngRoute"]);
var angularFormsApp = angular.module('homeIndex', ["ngRoute"]);
angularFormsApp.config(["$routeProvider",
function ($routeProvider) {
$routeProvider
.when("/", {
templateUrl: "templates/indexView.html",
controller: "HomeController"
})
.when("/About", {
templateUrl: "templates/aboutView.html",
controller: "AboutController"
});
}]);
angularFormsApp.controller("HomeController",
["$scope",
function ($scope) {
var x = 1;
}]);
angularFormsApp.controller("AboutController",
["$scope",
function ($scope) {
var x = 1;
}]);
The var x=1 has no meaning just for me to set a break point.
Below is indexView.html
<h3>Arrived at Index Page</h3>
aboutView.html
<h3>About Page</h3>
I also have the below in the _Layout.cshtml html tag to hook in angular
data-ng-app="#ViewBag.InitModule"
The problem seems to be that MVC is handling the routing that you expect to be handled by Angular.
Have a look at this question for some more information about having Both AngularJS and MVC in the same project:
Should I be using both AngularJS and ASP.NET MVC?
Here is a nice guide to getting started using the two together, it specifically touches on the routing as well:
Getting started with AngularJS and ASP.NET MVC
I hope that helps, please let us know if you need more information, or if something is not clear.
I have a small AngularJS application that use the route feature to render ng-view section. For some reason, the controller and view are not rendering as expected.
This is my application:
angular.module('sitesApp', ['ngRoute']);
var app = angular.module('sitesApp');
app.config(['$routeProvider', function ($routeProvider)
{
$routeProvider.when('/members/sites', {
templateUrl: '/members/_sites',
controller: 'SitesCtrl'
});
}]);
var controllers = {};
controllers.SitesCtrl = function ($scope)
{
alert('SitesCtrl loaded');
}
app.controller(controllers);
My application entry point is "/members/sites". When the user enter this URL, I want that the router will present the file "/members/_sites" in my ng-view.
This is how "/members/sites" looks like:
<div class="container" ng-app="sitesApp">
<ng-view></ng-view>
</div>
<script src="~/Scripts/app/Members/sites-app.js"></script>
This is how "/members/_sites" looks like:
<h1>Hello world!</h1>
Expected: SitesCtrl will be loaded and "Hello world" title will be presented on the screen.
Actual: Nothing. SitesCtrl controller wasn't loaded (no alert executed) and nothing on the screen.
I using angularjs 1.4.9 (with angular-route.min.js).
What the problem of this code?
How I can use On demand loading of controllers /services in angularJs. now I have a mainApp which referenced by Index.html. I am using $routeprovider to routing but all the required controller/services are referenced in the corresponding views eg:
<section id="pageLevelScripts">
<!--location of page level scripts-->
<script src="/Area/Sotaria/Controllers/UserController.js"></script>
</section>
<div class="row" >
<div class="col-lg-12">
<div class="row">
<div class="col-lg-12">
<ol class="breadcrumb">
<li>Home</li>
<li>Usermanagement</li>
<li class="active"><span>Users</span></li>
</ol>
<h6>{{name}}</h6>
</div>
</div>
This is my requirement I don't want to load all the controllers in my Index.html. but when I navigate to the childView, I am getting an error "Usercontroller is undefined", So how I can enable ondemanidng / lazy loading of controllers in angualrjs, .Ie. when ever the child page loaded ,then only its related controllers should load.
The reason you get undefined is because just loading the JS file doesn't make Angular aware of it. You must attach it to Angular's $controllerProvider.
You can create a custom service that does the lazy loading for you or use one of the many already built by other people. Here is an example of a custom one that you can use with requirejs.
If the below example is not explanatory enough you can read this blog post here: Strange Milk - Front End Development
Custom Provider
function LoaderProvider(){
this.controller = null;
this.directive = null;
this.filter = null;
this.factory = null;
this.service = null;
//service factory definition
this.$get = ['$q', '$rootScope', function($q, $rootScope){
return {
load: function (path) {
var q = $q.defer();
require([path], function () {
$rootScope.$apply(function () {
q.resolve();
});
});
return q.promise;
}
};
}];
}
var container = new LoaderProvider();
module.provider('Loader', function(){
return container;
});
Your Apps config:
.config(function (LoaderProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) {
// save references to the providers
LoaderProvider.controller = $controllerProvider.register;
LoaderProvider.directive = $compileProvider.directive;
LoaderProvider.filter = $filterProvider.register;
LoaderProvider.factory = $provide.factory;
LoaderProvider.service = $provide.service;
})
An example of how you would use this in your App's routes. Learn more about Resolve
resolve : {
load : ['Loader', function(Loader){
return Loader.load('../app/global/controllers/headerCtrl');
}]
}
Some other resources/solutions:
ocLazyLoad
angularAMD