AngularJS ng-click不在范围上调用函数

时间:2013-11-16 18:04:59

标签: javascript angularjs

我有一个自定义指令,它从webservice调用加载导航块。 我试图点击其中一个导航链接,我点了“ng-click”。 我试图点击应该在ng-click中调用函数的链接。该函数应该执行,但事实并非如此。

这是我的路由

var cartangularPublicShoppingApp = angular.module('cartangularPublicShoppingApp', [
  'ngRoute',
  'CategoriesController',
  'CategoryServices',
  'CategoryNavigationServices',
  'MenuModule'
]);
cartangularPublicShoppingApp.config(['$routeProvider',
    function($routeProvider) {
        $routeProvider.
            when('/cart', {
                templateUrl: 'partials/public/cart.html',
                controller: 'CartCtrl'
            }).
            when('/categories/:categoryId', {
                templateUrl: 'partials/public/categories.html',
                controller: 'CategoriesController'
            }).
            otherwise({
                redirectTo: '/categories'
            });
    }]
);

这是自定义指令

angular.module('MenuModule', [])
.directive('myCustomer', function() {
        return {
            restrict: 'E',
            templateUrl: './partials/public/customer.html',
            controller: function($scope, $sce, CategoryNavigationService) {

                var z = CategoryNavigationService.getCategoryNavigation().success(function(data){
                    $scope.categoryNavigation = data;
                    var navHTML = createCategoryNavigationBar(data);
                    var t = $sce.trustAsHtml(navHTML);
                    $scope.panes = t;

                }).error(function(data){

                        var error = "Get confident, stupid!";
                        var t = $sce.trustAsHtml(error);
                        $scope.panes = t;
                });
                function createCategoryNavigationBar(categoryNavigation){
                     var test = "";
                    var categoryId;
                    var catNavArray = categoryNavigation.categoryNavigationArray;
                     for(categoryId in catNavArray){
                         var currentCategoryNavigation = categoryNavigation.categoryNavigationArray[categoryId];
                            var string =  '<li> <a href="javascript:void(0);" name="categoryId" ng-click="getProductsForCategory()">' + currentCategoryNavigation.categoryName + "</a>";
                            test = test + string;

                         var count = 0;
                         var countingNavArr = currentCategoryNavigation.categoryNavigationArray;
                         for(var countingObject in countingNavArr){
                             count++;
                         }
                         if(count > 0){
                             var innerCategoryId;
                             test = test + "<ul>";
                             for(innerCategoryId in currentCategoryNavigation.categoryNavigationArray){
                                 var innerCategoryNavigation = currentCategoryNavigation.categoryNavigationArray[innerCategoryId];
                                 var innerTest = createCategoryNavigationBar(innerCategoryNavigation);
                                 test = test + innerTest;
                             }
                             test = test + "</ul>";
                         }
                         test = test + "</li>";
                    }
                    test = '<ul id="menu">' + test + '</ul>';
                    return test;



                }

            }
        };
    });

这是控制器,它被路由到我正在显示指令的html片段。

var categoriesControllers = angular.module('CategoriesController', []);

categoriesControllers.controller('CategoriesController', ['$scope', '$routeParams' , '$location', 'CategoryService',
  function($scope, $routeParams, $location, CategoryService) {

      var categoryId = $routeParams.categoryId;
      getProductsByCategoryIdServiceCall(CategoryService, categoryId);

      $scope.getProductsForCategory = function(){
          var categoryId = 4;
          getProductsByCategoryIdServiceCall(CategoryService, categoryId);

      }
      function getProductsByCategoryIdServiceCall(CategoryService, categoryId){
          CategoryService.getProductsByCategoryId(categoryId).success(function(data){
              $scope.productsDTO = data;
              $scope.name = "David M Pugh";
          }).error(function(data){
                  $scope.name = "David Q Pugh";
                  $scope.name = data;
          });

      }

  }]);

以下是categories.html中包含自定义指令的代码片段:

   <div class="row-fluid">
        <div class="span12">
            <div class="navbar">
                <div class="navbar-inner">
                    <div class="container" style="width: auto;">
                        <div class="span5"></div>
                        <div class="span2">
                            <div id="currentCategoryDropBoxMenu">

                            </div>
                        </div>

                    </div>
                </div>
            </div>
        </div>
    </div>
    <br />
  <my-customer></my-customer>
    <br />

我尝试更改在ng-click内部调用的javascript方法如下: ng-click =“getProductsForCategory”。

两个结果都是在单击链接时没有调用getProductsForCategory方法

有谁知道我的问题是什么?

感谢,

大卫

已编辑信息* 嘿伙计们,谢谢你们调查这个问题。它仍在进行中,但我为我的自定义指令

添加了一个额外的测试
<div ng-bind-html="panes"></div>
<a href="javascript:void(0);" ng-click="getProductsForCategory()">testing</a>

在唯一的行之前是第一个标记是div。 我添加了第二行,看看是否可能是html直接绑定到指令中的div标签,或者指令的配置是否存在问题。

我添加的第二个标签应该是标准的ng-click操作。我的第二个href标签 调用函数getProductsForCategory()。 所以它似乎是由于我将我的html字符串绑定到指令的div元素。

问题是我正在构建的导航结构可以有无限的嵌套子元素(它基本上是一个suckerfish选择框)。

这意味着我将不得不使用递归来映射每个父子导航 结构......在指令......

3 个答案:

答案 0 :(得分:1)

您在ng-click标记

中缺少一组大括号

ng-click="getProductsForCategory"

应该是

ng-click="getProductsForCategory()"

答案 1 :(得分:1)

我为我的项目想出了一个解决方案。 这是路由部分

var cartangularPublicShoppingApp = angular.module('cartangularPublicShoppingApp', [
  'ngRoute',
  'CategoriesController',
  'CategoryServices',
  'CategoryNavigationServices',
  'MenuModule'
]);
cartangularPublicShoppingApp.config(['$routeProvider',
    function($routeProvider) {
        $routeProvider.
            when('/categories/:categoryId', {
                templateUrl: 'partials/public/categories.html',
                controller: 'CategoriesController'
            })
    }]
);

这是视图(categories.html)的主控制器,用于显示我们的自定义指令。我创建了一个名为“treeFamily”的测试数据集,我将用它来测试该控制器中的指令

var categoriesControllers = angular.module('CategoriesController', []);

categoriesControllers.controller('CategoriesController', ['$scope', '$routeParams' , '$location', 'CategoryService',
  function($scope, $routeParams, $location, CategoryService) {

      $scope.treeFamily = {
          name : "Clothes",
          categoryId : "4",
          children: [{
              name : "Clothes",
              categoryId : "3",
              children: [{
                  name : "Men's Clothes",
                  categoryId : "2",
                  children: []
              },{
                  name : "Jackets",
                  categoryId : "1",
                  children: [
                      {
                          name : "Light Jackets",
                          categoryId : "4",
                          children: [{
                              name : "Natural Material",
                              children: []
                          }
                          ]
                      },{
                          name : "Heavy Jackets",
                          categoryId : "3",
                          children: []
                      }]
              }, {
                  name: "Pants",
                  categoryId : "4",
                  children: []
              }]
          }]
      }

这是我们将用于递归遍历数据集的指令。

angular.module('MenuModule', [])
.directive("tree", function(RecursionHelper) {
    return {
        restrict: "E",
        scope: {
            family: '=',
            'product': '&products'
       },

        templateUrl: './partials/public/family.html',
        compile: function(element) {
            return RecursionHelper.compile(element);
        }
    };
})

这是一个编译服务,我发现有人在线演示。 我决定使用它,因为它保持我们的代码整洁干净。

var categoryNavigationServices = angular.module('CategoryNavigationServices', []);
categoryNavigationServices.factory('RecursionHelper', ['$compile', function($compile){
    var RecursionHelper = {
        compile: function(element){
            var contents = element.contents().remove();
            var compiledContents;
            return function(scope, element){
                if(!compiledContents){
                    compiledContents = $compile(contents);
                }
                compiledContents(scope, function(clone){
                    element.append(clone);
                });
            };
        }
    };

    return RecursionHelper;
}]);

这是我们指令的html片段。请注意我们如何从指令中调用指令。

<a href="javascript:void(0);" name="categoryId" ng-click="product(family.categoryId)">{{ family.name }}</a>
<ul>
    <li ng-repeat="child in family.children">
        <tree family="child"  products="products(child.categoryId)"></tree>
    </li>
</ul>

以下是我的categories.html页面的一部分,该页面是我的控制器的主视图。

    <ul>
            <li ng-repeat="object in treeFamily.children">
                <a href="javascript:void(0);" name="categoryId" ng-click="products(object.categoryId)">{{object.name}}</a>
                <ul>
                    <li ng-repeat="child in object.children">
                        <tree family="child" products="products(child.categoryId)"></tree>

                    </li>
                </ul>
            </li>
   </ul>

我得到递归指令后我遇到的主要问题是我在指令的html中添加的ng-click在单击时没有响应。 这是因为该指令的范围是一个孤立的范围。

要访问主控制器的方法,必须将指令的方法绑定到控制器的方法。 为了做到这一点,你必须在标签内添加你想要绑定的控制器功能。 即:

<tree family="child" products="products(child.categoryId)">

并且指令的隔离范围引用了这个 即:

scope: {
            family: '=',
            'product': '&products'
       },

指令html中的a href是这样的:

<a href="javascript:void(0);" name="categoryId" ng-click="product(family.categoryId)">{{ family.name }}</a>

请注意,我们引用了指令的函数“product”,而不是product,这是我们想要访问的控制器上方法的名称。

答案 2 :(得分:0)

在指令中没有编译HTML的一件事似乎有问题。这是ng-click不起作用的原因,因为角度看不到这种变化。

var string =  '<li> <a href="" name="categoryId" ng-click="getProductsForCategory()">' + currentCategoryNavigation.categoryName + "</a>";

致电时:

 var navHTML = createCategoryNavigationBar(data);

尝试编写如下内容:

var temp = createCategoryNavigationBar(data);
var navHTML = angular.element(temp)($scope));

也许会有所帮助,

相关问题