Use ui-view as the template for state inside ui-router instead of an external template - angularjs

I have an app that is currently using the angular ui-router module dependency. The only aspect of the ui-router that I'm currently employing is the ability to apply/modify $stateParams to $scope and vice versa so the URL can change the way data is displayed in the controller to a user on arrival (i.e. url?param=something will filter the data by something).
I have the following in my app.config to set the state:
$stateProvider
.state('root', {
url: '/?param',
templateUrl: 'template.html',
controller: 'listController',
params: {
param: {
value: 'something',
squash: true
}
}
});
On my homepage, template.html successfully loads when the app is instantiated as such:
<div ng-app="myApp">
<div ui-view>
</div>
</div>
However, I have reached a roadblock and realize that calling the template from within templateUrl isn't going to work, as this app is being built inside another framework and therefore needs to be called from within the homepage itself to access its full capabilities.
Being a noob at AngualrJS, I was wondering if anyone can tell me what the best way is to accomplish this while still keeping the logic of $stateParams and other ui-router capabilities intact for the future.
For instance, could I just remove the templateUrl parameter from my state and call the controller directly inside the ui-view like this:
<div ng-app="myApp">
<div ui-view>
<div ng-controller="listController">
do something
</div>
</div>
</div>
I also looked into changing the entire logic from using ui-router to simply using the $location service but I'm wondering if there is a way to accomplish this without needing to over-do everything.

Related

ui-router child view of an angularjs component not showing

I have an angularjs component(almost empty markup) acting as a shell/parent to its child views(markups with different columns/formats). I am able to see the component but no child views are loaded.
ui-router config code:
.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('parent', {
url: '',
views: {
'parentComponent': {
component: 'parentComponent'
}
}
})
.state('parent.child', {
url: '/child',
templateUrl: 'child.html'
});
index.html:
<body ng-app="app" >
<div ng-controller='RoutingCtrl'>
<parent-component></parent-component>
</div>
</body>
The parent, which is a component:
<!DOCTYPE html>
<div>
<br />
<br />
<div>I am the parent, a angularjs component.</div>
<div>There sould be the nested/child view right below:</div>
<div ui-view></div>
</div>
child:
<div>Hi! I am the child!</div>
My controller tells ui-router to go to child view:
$state.go('parent.child');
I don't want to declare parent as abstract because, in my real app, I have views parallel to the parent component view(together, they form a multiple named view) here and these other high level views(except the parent component) must be visible regardless of the child views.
I am using angularjs 1.5.8 and ui-router version 0.4.2
Plunker:
http://plnkr.co/edit/tBhVTjttMagaJzHQNvro?p=preview
You haven't provided any details what you are trying to accomplish, so based on what it looks right now, you have two options: either go with the ui-view template throughout your app and use the parent-child relationship of ui-router or go with hybrid approach of loading your component, and inside it, a state you want to show.
Example with parent-child relationship - This example uses ui-view throughout the app. parent-component is loaded with it's own state and it's not abstract. This approach is good if you want to load different templates for different states in the same place.
Example with hybrid approach. This example follows your current app structure with parent-component loaded in index.html and a state loaded in your parent-component. You can see that you really don't need a parent state here as you have put your parent-component directly in index.html file. State child is loaded in inside your parent-component and it doesn't need a parent state.

How to update variables in ng-include view

I have a form and a view that shows data from that form. I want to separate form and view (which will be more that one).
Here is my code:
<div data-ng-controller="dataController" class="container">
<div data-ng-view></div>
<div ng-include="templates.simple" scope="data"></div>
</div>
And the included view shows initial data good, but does not react on any data change. How do I fix it?
data is and object with some fields.
templates.simple is a scope variable with template url
Code example: http://plnkr.co/edit/ibrsBaq8osYuEODGiM6O
The reason why binding is not working is you are reinitalizing an createDataController which is again creating data object for that ng-view template. This could be solve by removing createDataController controller from route.
Code
$routeProvider
.when('/', {
templateUrl: 'form.html',
//controller: 'createDataController'
})
Plunkr Here
Update
Other way would be if you want to load your controller twice still it doen't make any sense though. You could do this by writing ng-init on outside div, Instead of declaring that variable from controller.
<div data-ng-controller="createDataController" ng-init="data = {name: 'texy'}">
<div data-ng-view></div>
<div data-ng-include="'template.html'"></div>
</div>
Updated Plunkr

Changing attributes of enclosing containers based on current view

This is rather a conceptual than a strictly technical question.
I have the following index.html:
<div class="container"><div ng-view=""></div></div>
In my app.js, I have the following route configuration:
$routeProvider
.when('/questions', {
templateUrl: 'views/questions.html',
controller: 'QuestionsCtrl'
})
.when('/result', {
templateUrl: 'views/result.html',
controller: 'ResultCtrl'
})
.otherwise({
redirectTo: '/questions'
});
Which means that, based on the URL, different views are loaded in <div ng-view="">. Now, in order to have those views correctly rendered, I need to set style attributes on the enclosing <div class="container"> (I use Leaflet.js in one of those views and thus I need to temporarily set the width and height of the container to 100%, for a full screen map).
How would I do this best, i.e. "The Angular Way"? I looked at the $viewContentLoaded event of the ngView directive, but it doesn't seem to be the right thing as it seems to be only fired when the respective view is completely loaded and not at the initialization of the view (and thus the map, which needs a correctly styled container from beginning on). Should I use a controller that is defined on the body tag, for example? Or a service? I am completely clueless and want to make it right.
Use a controller that listens to $routeChangeSuccess on the $rootScope.
<body ng-app="X" ng-controller="app">
<div class="container" ng-class="containerClass">
<div ng-view=""></div>
</div>
</body>
angular.module('X').controller('app', function($rootScope, $route) {
$rootScope.$on('$routeChangeSuccess', function(){
$rootScope.containerClass = angular.lowercase(($route.current.controller || '').replace(/Ctrl$/, ''));
});
});

Angular ui-router reloading ng-include outside ui-view

Probably it's the entire layout wrong but here is my situation, I'm using a Meanjs.org stack with Angular ui-router.
I have a layout like this:
<div data-ng-include="'/modules/core/views/header.client.view.html'"></div>
<div id="page-content" class="clearfix" fit-height>
<div id="wrap" data-ui-view="" class="mainview-animation"></div>
</div>
Now I need to reload the controller inside the header.client.view.html when I change the $state.
For example when I'm in the sign-in page and I login I need to reload the header controller, but having this it's not possible because the ui-router change only the ui-view part with the relative template:
// this change only ui-view, doesn't care about the ng-include before
state('home', {
url: '/',
templateUrl: 'modules/core/views/home.client.view.html',
});
I found the possibility to add more ui-view to the state so I could add a ui-view2 for the header instead using the ng-include but this means having the ui-view2 on each state.
Any suggest?
You might not need to "reload the controller" every time the state changes, instead make your controller react to the state change on the fly and update its properties.
Check out the ui-router $stateChangeSuccess event.
First at all you need to listen #Matti Virkkunen
It's better to listen the state in your header's controller with "$stateChangeSuccess"
So you just have to declare a controller for your header. And inside your header controller add something like this.
$scope.$on('$stateChangeSuccess', function () {
// Do what you want for example check if the current state is home with $state.is('home');
});
Do not forget to declare your controller in your template
<div data-ng-controller="HeaderController" data-ng-include="'/modules/core/views/header.client.view.html'"></div>
<div id="page-content" class="clearfix" fit-height>
<div id="wrap" data-ui-view="" class="mainview-animation"></div>
</div>

using ng-view for hightly dynamic content?

I'm working on a website that allows you to search for different products, for example laptops. This is my index div:
<div class="content" id="main">
<div id="search-wrap">
<div id="logo"><h1>seach</h1></div>
<form id="search">
<input type="text" placeholder="Search " autofocus ng-model="query"/>
</form>
<div style="border: solid 1px blue" ng-show="query">
<ul ng-repeat="x in [] | range:10">
{{ query }}
</ul>
</div>
</div>
I have not yet implemented angular js on this but I'm thinking about how to do it. I'm not sure how to approach this, since its a complex site. Once a user searches for something, they will get results from a product. Will i have to create a different ng-view?
I'm just going by something i read online:
A page gets one ng-view. Assuming you have a single page application, this means you get one view. Use it wisely. Give some thought to what should be in the view. Is this your main content window or is this more of a navigation? Is the actual content (HTML) of this section highly dynamic? These are important decisions to make early in the development of your application if you have more than one distinct content area on your page.
Sorry if my question doesn't make sense, just not sure what to ask. Any tips will help.
thanks
You better try using ng-view and you would get more idea how it works.
There can be one ng-view in a page and it is tightly integrated with the url. When you change urls in browser, effective you are loading a different view into the ng-view area. These are configured using the $routeProvider.
ng-view is like the central content theme\area. Other views including sub-views for the main view and left nav, top nav footer is loaded using ng-include directive which has capability to compile and load any html chunk from server or locally.
For complex routing needs please have a look at ui-router which supports nested views.
For complex view you can try something like this
$stateProvider
.state('login', {
url: '/login',
controller: 'LoginController',
templateUrl: 'login.tpl.html',
access: 0
})
.state('multiple view', {
url: '/main',
access: 1,
views: {
'#': {
templateUrl: 'view1.tpl.html',
controller: 'view1Controller'
},
'page#dashboard': {
templateUrl: 'page.tpl.html',
controller: 'pageController'
}
}
})
More Info

Resources