search

Home  >  Q&A  >  body text

angular.js - How does AngularJS bind events to DOM elements added in JS

  var tpl = '<button ng-click="submitForm()" submit-form>' +
              'Submit'+
            '</button>'

  // 这两个方法都不work
  $scope.submitForm = function () {}
  angular.module('xxx', []).directive('submitForm')

Thanks for the answer!

phpcn_u1582phpcn_u15822774 days ago778

reply all(1)I'll reply

  • ringa_lee

    ringa_lee2017-05-15 16:51:34

    I don’t have time to write examples to support it, so I will briefly explain my understanding. I hope it will be useful to you.

    Under normal circumstances (that is, the DOM object is not dynamically inserted), the DOM object of the ng-click 这样的指令之所以有效(即点击之后能调用注册在可见作用域里的方法),是因为 angular 在 compiling phase(编译阶段)将宿主 DOM 对象(即加入了 ng-click directive is bound to the current scope.

    In other words, the current scope will only work if it knows there is this binding ng-click 的 DOM 对象存在,所以 ng-click.

    In your example, the HTML fragment is dynamically inserted into the DOM tree after the compiling phase. Even if you write ng-click, the current scope does not know the existence of this directive, so it will be invalid.

    Therefore, when you dynamically insert an HTML fragment, you need to manually call the $compile service and bind this DOM object to the current scope (or other visible scopes, depending on your application logic). The specific method is as follows:

    // 在某一个 controller 中,假设用 jQuery 动态插入一个 HTML 片段……
    $('selector').html(
      $compile(
        '<button ng-click="submitForm()">' + 'Submit' + '</button>'
      )(scope)
    );
    

    Note that you need to inject the $compile service first.

    In addition, this method is obviously too "disgusting". There is a better way (but a large number of dynamic insertions will cause performance losses) is to use the ng-repeat command, for example:

    <!-- 在要动态插入的地方…… -->
    <p class="form-control" ng-repeat="fragment in fragments">
      <button ng-click="submitForm()">{{fragment.text}}</button>
    </p>
    

    The fragments here is an empty array (initial state), so it fragments 就是一个空数组(初始状态),所以一开始这里 ng-repeat 不会有任何作用,然后你写一个方法来触发动态插入的动作,把一个类似 { text: 'Submit' } 这样的对象 push 到这个空数组中,ng-repeat 就会“帮”你把 DOM 对象插入了,并且 ng-repeat 本身就会重新 compile 内涵的 DOM 对象,因此 ng-click will not have any effect at first. Then you write a method to trigger the dynamic insertion action, and put a similar to { text: 'Submit' } push such an object into this empty array,

    will "help" you insert the DOM object, and

    itself will recompile the underlying DOM object, so submit-form 指令,因为没有必要。如果你要把它写成指令,那么你应该学习 ng-repeat 的方法,简单的说就是监视一个 expression(比如 item in items),当 items will work as you wish.

    🎜In the above two examples, I removed your submit-form directive because it is not necessary. If you want to write it as an instruction, then you should learn the 🎜 method, which simply means monitoring an expression (such as item in items). When items changes, Recompile the underlying HTML template. You can find the specific code, angular is open source. 🎜

    reply
    0
  • Cancelreply