如何在具有隔离范围的指令上使用ng-click?

时间:2016-10-14 16:17:18

标签: angularjs angularjs-directive angularjs-ng-click

当范围在指令上继承而不是在隔离时,我可以使用ng-click工作。 UPDATE: The point is that I want the click function to be defined as part of the directive... moving the function definition into a different scope is not what I want.

以下是继承范围的工作示例: https://codepen.io/anon/pen/PGBQvj

这是具有孤立范围的破碎示例; https://codepen.io/anon/pen/jrpkjp

(单击数字,它们在第一个示例中递增,但不在第二个示例中递增)

一些代码......

HTML

<div ng-app="myApp" ng-controller="baseController">
  <my-directive ng-click="hello()" current="current"></my-directive>
</div>

具有继承范围的指令:

angular.module('myApp', [])
    .controller('baseController', function($scope) {
    $scope.current = 1;
  })
    .directive('myDirective', function() {
    return {
      link: function(scope, element, attrs) {      
        scope.hello = function() {
          scope.current++
        };
      },
      replace: true,
      scope: true,
      template: '<div><child>      <strong>{{ current }}</strong></child></div>'
    }
    })
  .directive('child', function() {
    return {
      link: function(scope, element, attrs) {
        console.log("horeee");
      }
    }
  });

相同的指令,但具有独立的范围:

angular.module('myApp', [])
    .controller('baseController', function($scope) {
    $scope.current = 1;
  })
    .directive('myDirective', function() {
    return {
      link: function(scope, element, attrs) {      
        scope.hello = function() {
          scope.current++
        };
      },
      replace: true,
      scope: {
        current:'='
      },
      template: '<div><child>      <strong>{{ current }}</strong></child></div>'
    }
    })
  .directive('child', function() {
    return {
      link: function(scope, element, attrs) {
        console.log("horeee");
      }
    }
  });

5 个答案:

答案 0 :(得分:2)

问题在于您是否正在尝试调用未定义的函数。如果希望在Isolated指令中定义逻辑,则无需传入函数引用。

<my-directive current="current"></my-directive>

您无法在此处传递ng-click="hello()"。这是控制器的范围,因此hello()未定义。

相反,将ng-click事件移动到指令的模板

template: '<div ng-click="hello()">

还有一点: 您正在使用该指令的link()功能。这是为DOM操作保留的。相反,在hello()函数中定义controller

controller: function ($scope) {
  $scope.hello = function() {
      $scope.current++
  }
},

我认为这里存在更大的架构问题。隔离指令或组件的要点是将逻辑封装在自身内部。它不应该操纵外部状态。在此示例中,您将增加一个数字。如果在您的申请的另一部分中,您希望减少一个数字,该怎么办?使用递减逻辑复制指令将会导致很多代码重复。

相反,您应该在控制器中定义增量或减量功能,并将其传递给指令。

<my-directive change-number="increment()" current="current"></my-directive>

然后,使用&语法将函数引用绑定到指令:

scope: {
  current:'=',
  changeNumber: '&'
},

并从模板中调用changeNumber。这样做非常有助于代码重用。

答案 1 :(得分:0)

将hello函数添加到控制器。让它更新current的值并将其传递到指令的隔离范围

 .controller('baseController', function($scope) {
    $scope.current = 1;
    $scope.hello = function() {         
      $scope.current++;

    };

})

CodePen

答案 2 :(得分:0)

您需要将对象从控制器传递到指令

将你的js改为

angular.module('myApp', [])
.controller('baseController', function($scope) {
$scope.current = {};
$scope.current.val=1;
})
.directive('myDirective', function() {
return {
  link: function(scope, element, attrs) {      scope.internalcurrent= scope.current || {};
                                         //scope.internalcurrent.val=1;
    scope.internalcurrent.hello = function() {
      scope.internalcurrent.val++

    };
  },
  replace: true,
  scope: {
    current:'='
  },
  template: '<div><child>      <strong>{{ internalcurrent.val }}</strong></child></div>'
}
})
.directive('child', function() {
return {
  link: function(scope, element, attrs) {
    console.log("horeee");
  }
}
});

和你的html到

<div ng-app="myApp" ng-controller="baseController">
<my-directive ng-click="hello()" current="current"></my-directive>
</div>

答案 3 :(得分:0)

如果你想在指令中定义click函数,那么你需要在模板中附加处理程序,如下所示:

template: '<div ng-click="hello()"><child><strong>{{current}}</strong></child></div>'

当您将处理程序附加到指令声明时,就像在破坏的示例中一样,您基本上告诉您要在当前作用域(控制器的作用域)上调用函数。这可能看起来不像发生的事情,因为在您的工作示例中,您的函数是在myDirective中定义的,但它实际上是附加到范围,在这种情况下(工作示例)是控制器的范围。

CodePen

答案 4 :(得分:-1)

使用isolated指令,您可以使用ng-click="$parent.hello()"代替ng-click="hello()"。很高兴在你的问题上发布笔。

说明: 在元素上使用ng-click时,它的值(hello())将相对于它的外部范围进行计算,即示例中的控制器范围。当您创建使用非隔离范围的指令时,控制器的范围将传递给link函数,并且hello在控制器范围内定义。

//编辑代码:

angular.module('myApp', [])
    .controller('baseController', function($scope) {
    $scope.current = 1;
    $scope.hello = () => $scope.current ++;
  })
    .directive('myDirective', function() {
    return {
      link: function(scope, element, attrs) {      
      },
      replace: true,
      scope: {
        current:'='
      },
      template: '<div><child>      <strong>{{ current }}</strong></child></div>'
    }
    })
  .directive('child', function() {
    return {
      link: function(scope, element, attrs) {
        console.log("horeee");
      }
    }
  });