【问题标题】:Using a service in a directive (angularjs)在指令中使用服务(angularjs)
【发布时间】:2015-06-15 23:44:41
【问题描述】:

我已经用 angularjs 构建了一个应用程序,并创建了菜单指令,这些指令根据正在加载的视图应用。

这是我的菜单指令的结构:

angular.module('myApp')
 .directive('ogSection1Nav', function() {
  return {
    restrict: 'E',
    replace: true,
    templateUrl: '../scripts/directives/section1_nav.html',
    controller: function($scope, $location) {

      $scope.getClass = function(path) {
      var cur_path = $location.path().substr(0, path.length);
      if (cur_path === path) {
        if($location.path().substr(0).length > 1 && path.length === 1 )
          return "";
        else
          return "currentNav";
        } else {
          return "";
        }
      }

    }
  };
});

模板

<section class="adminMenu">      
  <nav class="side-nav">
  <ul>
      <li ng-class="getClass('/section1_summary')"><a href="#/section1_summary"><img title="Summary" src="images/summary.svg" title="Summary" height="25" /><span class="navText">Summary</span></a></li>
      <li ng-class="getClass('/section1_spot_list')"><a href="#/section1_spot_list"><img title="Spot List" src="images/postList.svg" title="" height="25" /><span class="navText">Spot List</span></a></li>
      <li ng-class="getClass('/section1_volume')"><a href="#/section1_volume"><img title="Volume" src="images/volumeHour.svg" title="" height="25" /><span class="navText">Volume</span></a></li>
      <li ng-class="getClass('/section1_location')"><a href="#/section1_location"><img title="Location" src="images/geography.svg" title="" height="25" /><span class="navText">Location</span></a></li>
      <li ng-class="getClass('/section1_media_type')"><a href="#/section1_media_type"><img title="Media Type" src="images/mediaType.svg" title="" height="25" /><span class="navText">Media Type</span></a></li>
   </ul>
 </nav>
</section>

getClass 函数检查当前位置并将其与 li 元素上 ng-class="getClass('/section1_volume')" 中定义的路径进行比较,并将 currentNav 类附加到当前页面。

现在我有一大堆这些菜单指令,不想总是在每个指令中重复相同的功能,所以我设置了一个服务如下:

angular.module('myApp')

.service('MenuState', function($location) {

   this.getClass = function(path) {
     var cur_path = $location.path().substr(0, path.length);
     if (cur_path === path) {
     if($location.path().substr(0).length > 1 && path.length === 1 )
       return "";
     else
      return "currentNav";
     } else {
     return "";
    }
   };

}); 

然后我在指令中调用 getClass 函数,如下所示:

angular.module('portalDashboardApp')
  .directive('ogAdvertisingMediatracNav', function() {
    return {
    restrict: 'E',
    replace: true,
    templateUrl: '../scripts/directives/advertising_mediatrac_nav.html',
    controller: function($scope, MenuState) {
          $scope.getClass = MenuState.getClass();
       }
    };
}); 

但是我收到以下错误:TypeError: Cannot read property 'length' of undefined

我认为这是因为路径变量没有传递给我的服务,但我不确定如何通过各种 ng-class="getClass('/path_name' )">我的菜单模板部分

【问题讨论】:

    标签: angularjs dependency-injection angularjs-directive angularjs-service


    【解决方案1】:

    通过将调用委托为以下方式,这可能对您有用:

    angular.module('portalDashboardApp')
    .directive('ogAdvertisingMediatracNav', function() {
       return {
           restrict: 'E',
           replace: true,
           templateUrl: '../scripts/directives/advertising_mediatrac_nav.html',
           controller: function($scope, MenuState) {
               $scope.getClass = function(path) {
                   return MenuState.getClass(path);
               }
           }
       };
    });
    

    【讨论】:

    • 太棒了!这样就成功了,路径变量现在被发送到我的服务中的 getClass 函数
    【解决方案2】:

    @appdJava 提出了一个很好的答案。或者,您也可以执行以下操作(无需调用 MenuState 的 getClass,因此删除括号):

    angular.module('portalDashboardApp')
    .directive('ogAdvertisingMediatracNav', function() {
       return {
           restrict: 'E',
           replace: true,
           templateUrl: '../scripts/directives/advertising_mediatrac_nav.html',
           controller: function($scope, MenuState) {
               $scope.getClass = MenuState.getClass;
               }
           }
       };
    });
    

    【讨论】:

    • 非常感谢这个解决方案。您能否解释一下 $scope.getClass = MenuState.getClass; 之间的区别?和 $scope.getClass = MenuState.getClass() 两者的解释有何不同?
    • 是的。不同之处在于,使用 $scope.getClass = MenuState.getClass() 您正在调用不带参数的 MenuState 服务的 getClass 函数,并将服务函数的返回值分配给 $scope.getClass。这将在执行函数时产生错误,因为存在预期的“路径”参数。但是如果你执行 $scope.getClass = MenuState.getClass,它只是将函数定义复制到 $scope 并且不会调用 eit。它仅在 ng-class="getClass('some path')" 的 html 中调用。这里它从 $scope 而不是 MenuState 调用函数
    • 啊哈,这是有道理的。感谢您扩展我的编码知识
    【解决方案3】:

    我确实认为问题出在您的服务上:

    this.getClass = function(path) {
     var cur_path = $location.path().substr(0, path.length);
     if (cur_path === path) {
     if($location.path().substr(0).length > 1 && path.length === 1 )
       return "";
     else
      return "currentNav";
     } else {
     return "";
    }
    

    };

    您的函数getClass 需要一个变量“路径”,并且您没有在函数调用$scope.getClass = MenuState.getClass(); 中应用此变量

    【讨论】:

    • 是的,这就是问题所在,但我不确定如何将该路径值传递给服务
    猜你喜欢
    • 2013-05-26
    • 2015-03-07
    • 2014-02-08
    • 2016-05-28
    • 2013-10-17
    • 1970-01-01
    • 2015-07-14
    • 2019-02-19
    • 1970-01-01
    相关资源
    最近更新 更多