【问题标题】:How to prevent redirecting <a href="#something"> in Angular Js1.2如何防止在Angular Js1.2中重定向<a href="#something">
【发布时间】:2013-11-28 11:49:32
【问题描述】:

我在我的应用程序中使用了 AngularJs-1.0.7 和 Bootstrap。最近我从 AngularJs-1.0.7 迁移到 AngularJs-1.2。我正在使用 Bootstrap 的 Accordions 和 Tabs。

Tab 的 HTML 代码包含&lt;a href="#id_for_content"&gt;,如下所示。

<ul id="myTab" class="nav nav-tabs">
    <li class="active"><a href="#firstTab" data-toggle="tab">Home</a></li>
    <li><a href="#secondTab" data-toggle="tab">Profile</a></li>
</ul>

<div id="myTabContent" class="tab-content">
    <div class="tab-pane fade in active" id="firstTab">
      <p>Content for first tab.</p>
    </div>
    <div class="tab-pane fade" id="secondTab">
      <p>Content For second tab.</p>
    </div>
</div>

在 Angular 的旧版本中,只有当我们提供像 &lt;a href="#/firstTab"&gt; 这样的锚标记时,才会发生路由更改。但是 AngularJs-1.2 重定向 &lt;a href="#firstTab"&gt;。它不考虑#firstTab 之间的/。因此,在单击 Tab 时,它会重定向到 http://web_url/#/firstTab 。如何解决这个问题?


我的解决方案

我找到了解决此问题的方法。我为标签写了一个指令。在该指令中,我检查了 href 属性。如果匹配,则阻止其默认行为。检查以下代码。

app.directive('a', function() {
    return {
        restrict: 'E',
        link: function(scope, elem, attrs) {
            if(attrs.href === '#firstTab'|| attrs.href === '#secondTab'){
                elem.on('click', function(e){
                    e.preventDefault();
                });
            }
        }
   };
}); 

但是这种方法的问题是,我必须在这里检查每个选项卡 ID 或手风琴 ID。如果我为它们使用动态 ID,则无法签入指令。

如果您能找到更好的解决方案,请告诉我们。

【问题讨论】:

  • 如果您使用class 指令会怎样?我的意思是,一个名为prevent-defaultrestrict: 'C' 的指令,如果没有if 部分,链接功能是相同的,那么您可以通过向其添加类"prevent-default" 来在任何地方使用它......就像&lt;a href="..." class="prevent-default"&gt;...&lt;/a&gt; 我猜我的也是一个hacky 解决方案,但比编写所有 id 更好。如果你愿意,我可以修改代码并作为答案发送。
  • if(/^#/.test(attrs.href)) 将适用于以# 开头的所有链接。
  • 尝试添加target="_self" 它通常会禁用链接上的角度路由。
  • 在这些基于 bootstrap angular-ui.github.io/bootstrap 的原生 Angular 指令中大量使用

标签: angularjs twitter-bootstrap migration


【解决方案1】:

如果您之前的答案没有成功,您可以尝试使用 $timeout... 在这种情况下,我使用了 AngularUI 选项卡...

vm.removeUserTab = function (user) {
    $timeout(function () {
        vm.activeTab = 0;
        var index = vm.userTabs.indexOf(user);
        vm.userTabs.splice(index, 1);
    });
};

【讨论】:

    【解决方案2】:

    归功于 https://prerender.io/js-seo/angularjs-seo-get-your-site-indexed-and-to-the-top-of-the-search-results/

    我的解决方案: - 在 app.js 中尝试添加“$locationProvider.hashPrefix('!');”

        .config(['$stateProvider', '$urlRouterProvider', '$httpProvider', '$locationProvider',
        function($stateProvider, $urlRouterProvider, $httpProvider, $locationProvider) {
        $stateProvider
        .state('menu', {
            url: '/',
            cache: false,
            abstract: true,
            templateUrl: 'static/www/templates/menu.html'
        })
        .state('menu.main_page', {
        url: 'app/main',
        cache: false,
        views: {
            'menuContent': {
              templateUrl: 'static/www/templates/mainpage.html',
              controller: 'MainCtrl'
            }
        }
        })
        $locationProvider.hashPrefix('!');
        $urlRouterProvider.otherwise(function ($injector, $location) {
            var $state = $injector.get('$state');
            $state.go('menu.mainpage');
        });
       }])
    
    • 在 index.html 中尝试添加

      &lt;meta name="fragment" content="!"&gt;

    正如上面所说的Marcel

    .directive('a', function () {
    return {
        restrict: 'E',
        link: function (scope, elem, attrs) {
            if (attrs.href && attrs.href.indexOf('#') > -1) {
                elem.on('click', function (e) {
                    e.preventDefault();
                });
            }
        }
    };
    })
    

    就是这样!为我工作!

    【讨论】:

      【解决方案3】:

      我想让您知道,还有另一种解决方案可以解决此问题(无需在控制器中定义函数)。

      您可以创建一个指令来阻止默认浏览器的行为(实际上是更改 URL):

      var PreventDefault = function () {
      
          var linkFn = function (scope, element, attrs) {
              $(element).on("click", function (event){
                  event.preventDefault();
              });
          };
      
          return {
              restrict: 'A',
              link: linkFn
          }
      };
      

      然后只需将指令添加到每个负责切换选项卡的a 元素,如下所示:

      <ul id="myTab" class="nav nav-tabs">
          <li class="active"><a href="#firstTab" prevent-default data-toggle="tab">Home</a></li>
          <li><a href="#secondTab" prevent-default data-toggle="tab">Profile</a></li>
      </ul>
      
      <div id="myTabContent" class="tab-content">
          <div class="tab-pane fade in active" id="firstTab">
            <p>Content for first tab.</p>
          </div>
          <div class="tab-pane fade" id="secondTab">
            <p>Content For second tab.</p>
          </div>
      </div>
      

      【讨论】:

        【解决方案4】:

        只需将其添加到您的链接中:

        target="_self"
        

        你准备好了;)

        【讨论】:

        • 对我不起作用 首页 (当前)跨度>
        • 您的href 非常通用。试试href="#something",我猜你确实已经在元素中有了这个锚。
        【解决方案5】:

        您在问题中的解决方案确实有效,但为了避免检查每个锚的 id,请更改

        if (attrs.href === '#firstTab'|| attrs.href === '#secondTab')
        

        if (attrs.href && attrs.href.indexOf('#') > -1)
        

        指令:

        .directive('a', function () {
            return {
                restrict: 'E',
                link: function (scope, elem, attrs) {
                    if (attrs.href && attrs.href.indexOf('#') > -1) {
                        elem.on('click', function (e) {
                            e.preventDefault();
                        });
                    }
                }
            };
        })  
        

        【讨论】:

          【解决方案6】:

          试试data-target="#something",它在开发和生产环境中都适合我。

          【讨论】:

          • 天哪,这太棒了!现在我不必只为模态使用 angular-strap 或 angular-ui,这更容易。
          【解决方案7】:

          这个问题我也有一段时间了,我只是偶然发现了这个问题(以及你自己的答案)。事实证明,您的解决方案几乎是正确的,只需稍作修改即可使其按您的意愿工作。

          除了您在使用选项卡时遇到的问题之外,我还遇到了下拉链接的问题——点击时它们会离开当前页面,而不是下拉菜单——事实上,这个问题存在于任何旨在切换某些东西的链接上,即设置了 data-toggle 属性。

          因此,对您的代码稍作修改以检查是否存在“切换”属性就可以解决这个问题:

          app.directive('a', function() {
              return {
                  restrict: 'E',
                  link: function(scope, elem, attrs) {
                      if(attrs.toggle){
                          elem.on('click', function(e){
                              e.preventDefault();
                          });
                      }
                  }
             };
          });
          

          希望这会有所帮助!

          【讨论】:

            【解决方案8】:

            一般情况下,您可以使用根作用域在所有作用域的原型上定义函数。在你的锚标签上添加 ng-click 并 将 $event 传递给 rootscope 处理程序。 Angular 也可以使用 ng-click 发送原始事件:

            <a ng-click="tabclick($event)">
            

            在模块的运行块中,您可以在 $rootScope 上设置 tabClick 函数

            $rootScope.tabclick = function ($event) { $event.preventDefault(); }
            

            这适用于任何范围,您不必检查特定的元素 ID。

            小提琴样例:http://jsfiddle.net/stto3703/wQe6P/

            干杯

            【讨论】:

            • 我使用了target="_self",而不是定义一个函数并调用它。
            • 您也可以使用&lt;a href="#" ng-click="tabclick(); $event.preventDefault();"&gt; 来避免将事件传递给每个处理点击的函数
            【解决方案9】:

            你可以使用 ng-click 在你的 JS 中调用一个函数。在该函数中,使用事件的 preventDefault 方法,并使用 $locationhash 方法更改 URL 中的哈希值。

            【讨论】:

            • 这不是一个好的解决方案。这里我需要在所有控制器中定义该函数。
            猜你喜欢
            • 2018-01-21
            • 1970-01-01
            • 1970-01-01
            • 2011-05-19
            • 2012-01-29
            • 1970-01-01
            • 1970-01-01
            • 2020-01-07
            • 2021-03-27
            相关资源
            最近更新 更多