angularjs ng-click在动态html元素上不起作用

时间:2018-08-20 23:44:47

标签: javascript jquery angularjs angularjs-controller

由于某些原因,当将此函数('testclickfn')用作ng单击动态元素时,它不会调用该函数。这是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>

我假设由于在angular加载页面后会生成“ click me”标签,所以在生成页面后它什么都不知道,因此ng-click =“ testclickfn()”不会被注册使用angularjs。

如何解决这种情况?

2 个答案:

答案 0 :(得分:1)

您正在以某种角度创建元素(完全不好的做法),但是不用担心,您可以让angular知道!

将控制器签名更改为

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

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

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

如果您不能确定,必须在控制器内部使用jquery选择器是不好的,则应该使用指令和link函数将元素附加到范围(即,如果您有多个testctrl元素,该怎么办) ?),但这会让您正常运行

答案 1 :(得分:0)

As promised

一般规则是,任何JS都不应该在angular函数之外,并且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