Pergunta

I'm a newbie to AngularJs. What I'm trying to do is update the page on hashchange events.

What I currently do (and know is not the "right" way to go) is:

<!DOCTYPE html>
<html>
<head>
<style>
    #hashdrop {
      display:block;
      border: 1px solid gray;
      width: 500px;
      overflow: auto;
      background-color: rgb(241,241,241);
      border-radius: 4px;
      text-align: center;
      vertical-align: middle;
      line-height: 100px;
      font-size: large;
      height: 100px;
    }
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script>
    var example = function($scope) {
      $scope.lastHash = location.hash.slice(1);
      $(window).on('hashchange', function (event) {
        $scope.lashHash = location.hash.slice(1);
        $scope.$apply();
      });
    };
</script>
<meta charset=utf-8 />
</head>
<body ng-app ng-controller="example">
  <div id="hashdrop" >
    {{lastHash}}
  </div>
</body>
</html>

(This can be copy-pasted into a blank html file and run. jsbin didn't detect the haschange correctly, for me.)

This doesn't really work. for some reason the value is not updated and I would assume there is a 'right' way to this in angularjs.
I would to understand how to do this right and more specifically how to correct the code in this example to work the "angular way".

Thanks!

UPDATE 1 Okay, After reading the comment about $location, I found some information and change my app to this:

<!DOCTYPE html>
<html>
<head>
<style>
    #hashdrop {
      display:block;
      border: 1px solid gray;
      width: 500px;
      overflow: auto;
      background-color: rgb(241,241,241);
      border-radius: 4px;
      text-align: center;
      vertical-align: middle;
      line-height: 100px;
      font-size: large;
      height: 100px;
    }
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script>
    angular.module('example',[]).config(function($locationProvider, $routeProvider) {
      $locationProvider.html5Mode(true);
    });
    var example = function($scope, $location) {


    };
</script>
<meta charset=utf-8 />
</head>
<body ng-app="example" ng-controller="example">
  <div id="hashdrop" >
    Hash = {{$location.hash()}}
  </div>
</body>
</html>

Still doesn't work. Nothing shows in output..

Foi útil?

Solução

AngularJs uses hashes in urls for all normal routing, it's the default way of navigating the page. You use the routeProvider to define url-schemas much like you would in back end MVC frameworks like Django, and the routeProvider will listen for changes in the hash and load new content accordingly.

I suggest doing the tutorial. It is fairly good (even if it misses a lot of stuff). Routes are demonstrated in step 7.

Just warning. Angular assumes that you use hashes as your main way to handle urls and routing, so routeParams will not let you change only part of a page when changing the hash part of the url. To do that you would either switch to using get parameters or use something like ui-router which is more flexible.

Outras dicas

You can bind to the hashchange event using angular.element instead of jQuery, potentially reducing dependencies.

Include this in your controller.

angular.element(window).bind('hashchange', function() {
  console.log('hash has changed');
});

This code will log "hash has changed" when the hash changes.

Not sure it will solve your problem (there's some more funky stuff in your code, as Kevin Beal pointed out), but it's kind of unclear what you're saying "doesn't work".

Worth noting that angular.element uses jQuery if it's available, so if you want to use jQuery anyways, angular.element(window) won't do anything differently than $(window).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top