angular 路由去除#號


1.  路由啟動          $locationProvider.html5Mode(true);  通過pushstatex修改url

app.js

define([
    'angular',
    "App/Ctrl/controllers",
    "App/Directive/directive",

    "angularRoute"
], function (angular,controllers,directives,appDirec) {
    var app=angular.module('myApp', ["ngRoute",controllers.name,directives.name])
    templete="/front/propertyEntrust/view/templete"
   /* /limitSell/add?propertyId=33 */

    app.config(['$routeProvider',"$locationProvider", function ($routeProvider,$locationProvider) {

        $locationProvider.html5Mode(true);

        $routeProvider.when('/detail/:Id', { //詳情頁面
            templateUrl: templete+'/detail.html'
        });

        $routeProvider.when('/rent/add/:propertyId', {  //一般出租
            templateUrl: templete+'/rent.html'
        });

        $routeProvider.otherwise({redirectTo: '/rent'});
    }]);

    return app
});

 

 2. 設置前端路由開始的字段 即服務器路由的最后的字段

 <base href="/fy/propertyEntrustApply/index/">  

  

小注:angular在此處使用html5的base標簽來做baseurl的配置,而不是提供API 配置baseurl 非常巧妙,充分利用了html5  base標簽的特性。  debug  所有$0.href   發現都自動加上了了“/client.app/index”.

 這樣在模板 或者.routeprovider 配置路由的時候就不需要在另外拼裝上baseurl了。節省了很多對url邏輯的處理。 但是 如果是script加載腳本 相對路徑的話 可能會與base的配置沖突,我的項目使用requirejs一類的包加載器解決問題

 

3,后端配置重定向  nodejs為例

app.get('/fy/propertyEntrustApply/index/*', function (req, res) {
    res.render("a", {});
});

 如上所示     http://localhost:3000/fy/propertyEntrustApply/index/rent/add/21

/fy/propertyEntrustApply/index/  為服務器路由  指向a.ejs

之后/rent/add/21  就是前端路由了

 

源碼小解:

對路由監聽路由其實是監聽rootscope,  loaction.path()的修改會自動更新rootscope,所以對location.path()的作用其實類似backbone的navigate(), 邏輯是手動走了路由隨后更改url的值,而不是相反。

其次 angular對視圖內的所有超鏈接做了事件代理

    $rootElement.on('click', function(event) {
      // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
      // currently we open nice url link and redirect then

      if (event.ctrlKey || event.metaKey || event.which == 2) return;

      var elm = jqLite(event.target);

      // traverse the DOM up to find first A tag
      while (lowercase(elm[0].nodeName) !== 'a') {
        // ignore rewriting if no A tag (reached root element, or no parent - removed from document)
        if (elm[0] === $rootElement[0] || !(elm = elm.parent())[0]) return;
      }

      var absHref = elm.prop('href');

      if (isObject(absHref) && absHref.toString() === '[object SVGAnimatedString]') {
        // SVGAnimatedString.animVal should be identical to SVGAnimatedString.baseVal, unless during
        // an animation.
        absHref = urlResolve(absHref.animVal).href;
      }

      var rewrittenUrl = $location.$$rewrite(absHref);

      if (absHref && !elm.attr('target') && rewrittenUrl && !event.isDefaultPrevented()) {
        event.preventDefault();
        if (rewrittenUrl != $browser.url()) {
          // update location manually
          $location.$$parse(rewrittenUrl);
          $rootScope.$apply();
          // hack to work around FF6 bug 684208 when scenario runner clicks on links
          window.angular['ff-684208-preventDefault'] = true;
        }
      }
    });

 可以看到, 點擊超鏈接的默認行為被禁止,如果超鏈接是負責路由跳轉的時候,獲得路由的url, 手動執行$rootScope.$apply();

   注意$().prop  與$().attr()的區別  主要在$().attr() 拿的是$0.href, $().prop拿的是$0.getAttribute("href") , 此處需要去除 base路徑的拼裝,只拿前端路由。所以使用$().prop

 

 

 

 $rootScope.$watch(function $locationWatch() {
      var oldUrl = $browser.url();
      var currentReplace = $location.$$replace;
    
      if (!changeCounter || oldUrl != $location.absUrl()) {
        changeCounter++;
        $rootScope.$evalAsync(function() {
          if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl).
              defaultPrevented) {
            $location.$$parse(oldUrl);
          } else {
            $browser.url($location.absUrl(), currentReplace);
            afterLocationChange(oldUrl);
          }
        });
      }
      $location.$$replace = false;
    
      return changeCounter;
    });
    

angular 會watch rootscope,當rootscope更新的時候 $browser.url()  H5模式啟用的條件下  調用pushstate 修改瀏覽器 url的值,最后afterLocationChange(oldUrl),廣播 $locationChangeSuccess 事件。

然后在 angular-rout.js  ngroute模塊中會監聽$locationChangeSuccess 事件,執行路由模塊的邏輯。

$rootScope.$on('$locationChangeSuccess', updateRoute);

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM