angularjs ng-click 不适用于动态 html 元素

angularjs ng-click not working on dynamic html elements

出于某种原因,当使用此函数 ('testclickfn') 作为 ng-click 动态元素时,它不会调用该函数。这是 angularjs 文件:

app.controller('testctrl',function($scope){
     testfn($scope);

     $scope.showelements = function(){
        displayTestRows();
     }
});

function testfn($scope){
   $scope.testclickfn = function(){
     alert('testing click fn');
   };
}

function displayTestRows(){
   for(var i=0; i < 5; i++){
      $("#testdiv").append('<p ng-click="testclickfn()">click me</p><br>'); 
   }
}

HTML 调用 angularjs 控制器的页面 'testctrl':

<div id="testdiv" ng-controller="testctrl">
   <button ng-click="showelements()">Show dynamic elements</button><br>
</div>

我假设 'click me' 标签是在 angular 加载页面后生成的,它在页面生成后什么都不知道所以 ng-click="testclickfn()" 没有在 angularjs 中注册。

我该如何解决这种情况?

您正在以 angular 不知道的方式创建元素(非常糟糕的做法),但不用担心,您可以让 angular 知道!

将控制器签名更改为

controller('testctrl', function($scope, $compile) {

然后运行手动编译新元素以激活ng-click指令

$scope.showelements = function(){
    displayTestRows();
    $compile($("#testdiv").contents())($scope);
}

如果你不知道,必须在你的控制器中使用 jquery 选择器是不好的,你应该使用一个指令和 link 函数来将元素附加到范围(即,什么如果你有多个 testctrl 元素?),但这会让你 运行ning

一般规则是 angular 函数之外不应有任何 JS,并且 DOM 操作,在适当的情况下也应由 angular 处理。

示例 1:功能强大

Have a look

<div ng-controller="ctrl">
  <button ng-click="show('#here')">
    create
  </button>

  <div id="here">
    I'll create the clickables here.
  </div>
</div>

将控制器用于在许多不同事物之间共享内容的事物

  .controller('ctrl', ['$scope', '$compile', function($scope, $compile) {
    $scope.sharedVariable = 'I am #';

    $scope.show = function(where) {
      where = $(where).html('');

      //lets create a new directive, and even pass it a parameter!
      for (var index = 0; index < 5; ++index)
        $('<div>', {'test':index}).appendTo(where);

      $compile(where.contents())($scope);
    };
  }])

对每个都有自己状态的非唯一元素使用指令

  .directive('test', function() {
    return {
      //these too have their own controllers in case there are things they need to share with different things -inside them-
      controller : ['$scope', function($scope) {
        $scope.test = function() {
          //see, no selectors, the scope already knows the element!
          $scope.element.text(
            //remember that parent controller? Just because we're in another one doesnt mean we lost the first!
            $scope.$parent.sharedVariable +
            $scope.index
          );
        }
      }],

      //no need to do things by hand, specify what each of these look like
      template : '<p>click me</p>',

      //the whole "angular way" thing. Basically no code should be outside angular functions.
      //"how do I reference anything in the DOM, then?"; that's what the `link` is for: give the controller access using `scope`!
      link : function(scope, element, attributes) {
        //you can assign "ng-click" here, instead of putting it in the template
        //not everything in angular has to be HTML
        scope.element = $(element).click(scope.test);
        //did you know you can accept parameters?
        scope.index = Number.parseInt(attributes.test) + 1;
      },

      //just some set up, I'll let you look them up
      replace : true,
      restrict : 'A',
      scope : {}
    };
  })

示例 2:简单

但这只是一种非常通用且功能强大的做事方式。这完全取决于您需要做什么。如果这个非常简单的例子确实是你需要做的全部,你可以制作一个非常简单的,几乎所有-html版本:

<div ng-controller="ctrl">
  <button ng-click="items = [1, 2, 3, 4, 5]">
    create
  </button>

  <p ng-repeat="item in items" ng-click="test($event)">
    <span>click me</span>
    <span style="display:none">I am #{{item}}</span>
  </p>
</div>
.controller('ctrl', ['$scope', function($scope) {
  $scope.test = function($event) {
    $($event.currentTarget).children().toggle();
  };
}])

就是这样,works the same almost