2

Sorry if this is a bit of a newby question. I'm trying to create a login page that has a background image, while the rest of my pages do not. I've used ng-style but I can't get the property to update on page changes. in my index.html:

<body ng-app="myApp" ng-style="bodyStyle" ng-controller="bodyController">
  //content
</body

bodycontroller:

var image="http://momentumbooks.com.au/wp-content/uploads/2013/06/space.jpg";
if ($location.path() === '/login') {
  $scope.bodyStyle = {background: "url(" + image + ") no-repeat center center fixed"};
} else{
  $scope.bodyStyle={background: ""}
} 

Obviously this doesn't work because the function is only called once. I've tried using rootScope, but I can't seem to use rootScope properties in ng-style (and everywhere i look, people are advising against using rootScope for this purpose). How do I create a dynamic background? Also i'd prefer not to use a controller on my body tag, if possible.

update

The main problem i'm having is that the background image does not update when changing paths. The image is set in bodycontroller, and when logging in and changing paths it is not changed.

Per suggestion I could write a service, I've used them before but only through getters and setters, so I assume i can create a service that sends a call to a controller? Looking something like this:

<body ng-app="myApp" ng-style="bodyStyle" ng-controller="bodyController">
   //content
</body

bodycontroller

var image=??;
$scope.bodyStyle = {background: "url(" + image + ") no-repeat center

some service

 .service('backgroundService', function (image) {
    var backgroundImage = image
    // somhow set bodycontroller image?
 });

and then somehow call the service when route is changed? I haven't found a way to inject services into my router config, which is what I think i would need for that.

Mischa
  • 2,069
  • 4
  • 23
  • 32
  • So to clarify, do you want to have the background change when the $location.path() changes? Or after certain times? – Guinn Jun 22 '15 at 13:58
  • When the location.path() changes. Basically I want a background for the login page but not anywhere else. So I figured the easiest way would be to do that based on the current path. But Other suggestions are welcome – Mischa Jun 22 '15 at 14:01
  • You can set the background to a div inside the login view, instead of the body... but if you still trying this way you can check this directive http://stackoverflow.com/a/15537359/1666722 – Facundo Pedrazzini Jun 22 '15 at 14:04
  • I've tried a seperate div. But because the login page is ng-view, the div is inside the body and even inside a container so I can't set background to the entire page. The link has the same problem I've found everywhere. The ng-style is not changed when I log in, only on page refresh. – Mischa Jun 22 '15 at 14:08
  • Do you have a html file for your login page then? Because if you do, why not simply add css to that template to have a background image? – Guinn Jun 22 '15 at 14:11
  • 1
    I recommend you to change the structure of your layout, and put the container div inside the ng-view so you can add content with full width... but if you dont want to do it check the directive I paste you in my last comment (is the answer of mythz with 34 points) – Facundo Pedrazzini Jun 22 '15 at 14:12
  • Is your login page a html file template loaded in a ng-view? Cause if so, why not style the login page to have a background image? – Guinn Jun 22 '15 at 14:41
  • @Guinn, it is a html file within ng-view. But when i try to style the login page it doesn't show a background image. How would you suggest I do this? – Mischa Jun 22 '15 at 14:43
  • Uh, suppose you have a 'main' div on your page, just add the background image to that css class. You dont have to add it dynamically, simply hard-code it in the css file with the css code you wanted to apply with ng-styles – Guinn Jun 22 '15 at 14:45

2 Answers2

2

So i figured out an easy way to do this with some help.

in app.js add this:

.run(function ($rootScope, $location) {
  $rootScope.$on( "$routeChangeStart", function(event, next, current) {
    $rootScope.bodyClass = $location.path().replace('/', '') + '-page';
  });
});

and change index to:

<body ng-app="myApp" ng-class="bodyClass">

and Css:

.login-page {
  background: url("someImage") no-repeat center center fixed;
}
Mischa
  • 2,069
  • 4
  • 23
  • 32
1

IMO it would be easier to just toggle an ng-class based on location. So you could do something like -

if ($location.path() === '/login') {
$scope.isLogin = true;
} else{
$scope.isLogin = false;
}

then on the html

<body ng-app="myApp" ng-class="{'customBgClass' : isLogin }" ng-controller="bodyController">

Then just set everything you want on that css class

.customBgClass {
   background: url("http://momentumbooks.com.au/wp-content/uploads/2013/06/space.jpg") no-repeat ce;ter center fixed;
 }
ajmajmajma
  • 13,712
  • 24
  • 79
  • 133
  • Unfortunately this doesn't solve my main problem. The controller is only called once when the app is loaded (and on refresh). So the $scope.isLogin is not changed when a user logs in. – Mischa Jun 22 '15 at 14:06
  • @Mischa that is a separate problem then. You would need a service to handle all of this. My recommendation is a service that is injected into each instance that checks this each time you swap a page. If you're using routing this is pretty much built in. – ajmajmajma Jun 22 '15 at 14:12
  • Correct, but it's the main problem i'm having. I've tried making a service but couldn't get it to work. So if you have an example i'd be grateful. – Mischa Jun 22 '15 at 14:15
  • @Mischa I did not interpret that from how you worded your question. You either want to use routing (what are you using for routing now?) I think ui-router has a way to do this very easily. Otherwise you want to create a new module and inject it in where ever you are using it, that service would do your logic ($location.path() === '/login') and send back something to wherever you have it injected. Right now you have the logic inside 1 scope which is in the login screen, so yes it will not work elsewhere. It really depends how you set up your app, but I would recommend a service. – ajmajmajma Jun 22 '15 at 14:20
  • @Mischa so you would create a service - https://docs.angularjs.org/guide/services . Probably just a .service because you only need a singleton to check the url once on landing, that would send the result into the controllers and se whatever you needed. – ajmajmajma Jun 22 '15 at 14:22