Angular Data Service across two cshtml pages - angularjs

I need to share data across controllers. So I have my shared array returned from a service and then inject the service into any controllers that need to access it.
angular.module('mappingLayers', [])
.constant('MODULE_VERSION', '0.0.3')
.service('layersAvailableToMap', function () {
return [];
});
;
I'm also using the MVC4 template, and the RenderBody calls one of two different index.cshtml
pages/views
_Layout.cshtml
<header>
<div class="content-wrapper">
<div class="float-left">
<p class="site-title">My Title</p>
</div>
<div class="float-right">
<section id="login">
Hello, <span >#User.Identity.Name</span>
</section>
<nav>
<ul id="menu">
<li>#Html.ActionLink("Portfolio", "Index", "Home")</li>
<li>#Html.ActionLink("Profile", "Index", "Profile")</li>
</ul>
</nav>
</div>
</div>
</header>
<div data-ng-app="portfolioApp">
<section >
#RenderBody()
</section>
</div>
The problem arises when I switch between index.cshtml pages (via Portfolio and Profile ActionLinks and rendered through RenderBody()) and my shared data service array gets recreated - i.e. one for each page.
So, the question is, how do I share my service across controllers in different pages rendered via RenderBody from my _layout page.
Injecting the service in multiple controllers within one of the pages works fine.
Incidentally, switching between the two index.cshtml pages (i.e. calling RenderBody) seems to cause a full page refresh/callback, when I don't think it should. This might point towards the problem?
Thanks.

Related

AngularJS view without using main ui-view template?

I'm creating an application that provides a logged in user with the ability to create a poll (with questions and choices) in their dashboard.
Once the poll has been created I would like to redirect to the poll page, which will have a unique url (ex: http://example.com/p/3eRr4g6).
I would like this page to NOT use the dashboard template.
How does one accomplish this?
Here's my dashboard view:
Example Poll Page/Template:
UPDATE: To show my current index file and how I have it structured. (In reply to koox00's response)
<body class="hold-transition skin-purple sidebar-mini">
<div class="wrapper">
<div ng-include="'components/navbar/navbar.html'"></div>
<div ng-include="'components/sidebar/sidebar.html'"></div>
<div class="content-wrapper">
<div ui-view></div>
</div>
<div ng-include="'components/footer/footer.html'"></div>
</div>
</body>
You can use named views.
Create a state that loads the default template in that view e.g main and make every other state a child of this one if you want to share data.
In the desired state you can load over the main view the html you want.
update
default.html
<div class="wrapper">
<div ng-include="'components/navbar/navbar.html'"></div>
<div ng-include="'components/sidebar/sidebar.html'"></div>
<div class="content-wrapper">
<div ui-view></div>
</div>
<div ng-include="'components/footer/footer.html'"></div>
</div>
index.html
<body>
<div ui-view="main"></div>
</body>
take a look at nested states also if you want to share data between states parent/child.

My directive stopped working when I started using ng-repeat with a different controller. What am I doing wrong?

So I followed this guide so I could have a nav bar on every page: http://tomaszdziurko.pl/2013/02/twitter-bootstrap-navbar-angularjs-component/
And it was working, until I created a separate controller to populate my bootstrap carousel. The thing is, my ng-repeat works fine, but when it does I can't see my navbar on that page. I can see it just fine on other pages. I believe this is a scoping issue, but I am not sure where.
This is what I have in the main body of this page:
<body>
<reusable-navbar></reusable-navbar>
<!-- Carousel Start -->
<div id="main-carousel" class="carousel slide container" data-ride="carousel">
<!-- Wrapper for slides -->
<div class="carousel-inner">
<!--Must set this by hand-->
<div class="item active">
<img alt="" src="../Revamp/Images/carousel/1.jpg">
</div>
<!--Repeat through the rest-->
<div ng-controller="carouselPhotoController">
<div class="item" ng-repeat="source in source">
<img alt="" ng-src="{{source.source}}">
</div>
</div>
</div>
</div>
And my controller looks like this:
var carouselPhotoController=angular.module("revampApp", []);
carouselPhotoController.controller("carouselPhotoController", function($scope, $http){
$http.get('../Revamp/Images/carousel/photos.json').success(function(photos){
//Carousel photos
$scope.source = photos;
})
});
And the directive is identical to the one in that walk through, just with a different template. So how to I get it so my nav bar will show up AND I can use ng-repeat?
Make sure you are not recreating the app.
This creates a new app:
var carouselPhotoController=angular.module("revampApp", []);
But this only accesses an app already created (note the absence of the second parameter):
var carouselPhotoController=angular.module("revampApp");
Change the above line and it should work.

angular controllers, multiple templates, and passing scope values from controllers to master page

I'm starting a new project and am going to be using angular in a "single page architecture" application. I'm a little new to angular.
So, I purchased a template for my site. It has 2 distinct layouts that I would like to use. 1 for my unauthenticated (marketing) pages and another for most of my authenticated pages.
The difference in each is subtle, but the inside pages require a class on the <body> tags that the outside pages cannot have. I considered using 2 layouts but then that got tricky as I started thinking about how I would lay out my urls.
My thought is to use angular to manage my layout so that I only need one master page like this:
<body ng-class="{menu-right-hidden: isInternalPage }">
<div class="container-fluid">
<div ng-if="isInternalPage" id="menu" class="hidden-print hidden-xs sidebar-blue sidebar-brand-primary">
<!-- sidebar content -->
</div>
<div id="content">
#RenderBody()
</div>
<div class="clearfix"></div>
<div ng-if="isInternalPage" id="footer" class="hidden-print">
<!-- internal footer -->
</div>
<div ng-if="!isInternalPage" id="footer" class="hidden-print">
<!-- external footer -->
</div>
</div>
</body>
My question is this: Is there an easy way to set isInternalPage (and possibly other valies) without having $scope.isInternalPage = true/false; decorating all of my controllers?
You could use ng-init and define a scope variable on $rootScope:
<body ng-init="$root.isInternalPage = true" ng-class="{menu-right-hidden: $root.isInternalPage }">
<div class="container-fluid">
<div ng-if="$root.isInternalPage" id="menu" class="hidden-print hidden-xs sidebar-blue sidebar-brand-primary">
<!-- sidebar content -->
</div>
<div id="content">
#RenderBody()
</div>
<div class="clearfix"></div>
<div ng-if="$root.isInternalPage" id="footer" class="hidden-print">
<!-- internal footer -->
</div>
<div ng-if="!$root.isInternalPage" id="footer" class="hidden-print">
<!-- external footer -->
</div>
</div>
</body>
Alternatively, you could assign your variable on $rootScope inside one of your controllers:
app.controller('ctrl', function($rootScope) {
$rootScope.isInternalPage = true;
});
What you can do in this case is create an AngularJS service: "You can use services to organize and share code across your app"
angular.module('core').service('GlobalVars', [ 'addDependenciesHere',
function(addDependenciesHere) {
this.isInternalPage = someVal ? true : false
}
]);
Then inject this into the constructor for each controller
angular.module('core').controller('HomeController', ['$scope', 'GlobalVars',
function ($scope, GlobalVars) {
$scope.globals = GlobalVars;
}
]);
Then in your view you can access this directly
<body ng-class="{menu-right-hidden: globals.isInternalPage }">

angular 1.2, how would a router load views without making get calls?

I've been going over the current (angular 1.2.16) routing and multiple views method for angular. Its detailed here. In this we see that for every route there is a get request to load the partial html.
How would I change this so all get requests for views happen when the app instantiates and then the routes switch the views without making further calls to the server?
Suppose that you want to change the content of a div depending on what is stored in data.mode. You need to have first a mechanism to change the value of data.mode and that's entirely up to you.
<div ng-switch on="data.mode">
<div ng-switch-when="first_value">
<!--Your first partial page content-->
</div>
<div ng-switch-when="second_value">
<!--Your second partial page-->
</div>
<div ng-switch-when="second_value">
<!--Your third partial page-->
</div>
<div ng-switch-default>
<!--Default content when no match is found.-->
</div>
</div>
You can do what they suggest here and use ui-router
i.e.
<!-- index.html -->
<body>
<div ui-view="viewA"></div>
<div ui-view="viewB"></div>
<!-- Also a way to navigate -->
<a ui-sref="route1">Route 1</a>
<a ui-sref="route2">Route 2</a>
</body>

Is it possible to add template trough angular.js from outside of ng-view?

I want to have a login view outside ng-view, but is it even possible with angular.js? couldnt find any examples of folowing on the internet. Example is descibed below.
<div class="container">
<div class="header">
<div class="loginView"> my huge login view</div>
</div>
</div>
<div class="container">
<div ng-view></div>
</div>
Yes. Assign a controller to the loginView and treat it like any other view.
ng-view is just used when using the $routeProvider to define routes.
This is perfectly valid. ngView is used to complement the router. This means it is just a directive as any other. You can put anything around it.
It sounds like you want something like this: Live demo here (click).
<div class="container">
<div class="header">
<div class="loginView" ng-include="'login.html'"></div>
</div>
</div>
You could also include your file from a $scope property like this:
$scope.foo = 'login.html';
<div ng-include="foo"></div>

Resources