javascript - AngularJS - 处理现有 DOM 元素上的点击事件

标签 javascript angularjs angularjs-directive angularjs-scope dom-events

我正在尝试使用 Angular 捕获现有 DOM 项目选择上的点击事件:

(node tree on the left)

代码如下:

<!-- 
HTML template (section) - it's a django template, i kept the 
django template syntax as original, using '{{' and '}}', and for 
AngularJS templating's system '{$' and '$}'
-->
<fieldset class="module aligned">
    <h2>Document's sections</h2>

    <div class="form-row document-nodes" ng-app="DocumentNodesApp">
        <div style="width: 100%; min-height: 450px;"
             ng-controller="NodeController" on-node-click="getNodeTitle($event)">
            <form id="changelist-form" action="" method="post" novalidate>{% csrf_token %}
                <div id="tree"
                     data-url="{{ tree_json_url }}"
                     data-save_state="{{ app_label }}_documentnode"
                     data-auto_open="{{ tree_auto_open }}"
                     data-autoescape="{{ autoescape }}"
                >
                </div>
            </form>
            <div id="node-container">
                {$node_title$}
            </div>
        </div>
    </div>
</fieldset>


/* DocumentNodeApp js code */

var app = angular.module('DocumentNodesApp', []);

app.config(function($interpolateProvider) {
    $interpolateProvider.startSymbol('{$');
    $interpolateProvider.endSymbol('$}');
});

var nodeController = app.controller(
        'NodeController',
        function($scope){
             $scope.node_title = "Click on a node...";
             $scope.getNodeTitle = function(event){
                 alert(event);
             }

        });
app.directive(
    "onNodeClick", function(selector, $parse){
        // connect the Angular context to the DOM events
        var linkFunction = function($scope, $element, $attrs){
            //get the scope expression, will be evaluated on
            // the scope when the document is clicked
            var scopeExpression = $attrs.onNodeClick;

            var invoker = $parse(scopeExpression);

            $(selector).on("click", function(event){
               $scope.$apply(
                   function(){
                       invoker(
                           $scope, { $event: event}
                       )
                   }
               );
            });
        }
        return( linkFunction );
    }
);

重新加载页面后,控制台中出现此错误:

Error: [$injector:unpr] http://errors.angularjs.org/1.3.2/$injector/unpr?p0=selectorProvider%20%3C-%20selector%20%3C-%20onNodeClickDirective
    at Error (native)
    at http://127.0.0.1:8050/sitestatic/js/angular.min.js:6:416
    at http://127.0.0.1:8050/sitestatic/js/angular.min.js:38:60
    at Object.d [as get] (http://127.0.0.1:8050/sitestatic/js/angular.min.js:36:74)
    at http://127.0.0.1:8050/sitestatic/js/angular.min.js:38:132
    at d (http://127.0.0.1:8050/sitestatic/js/angular.min.js:36:74)
    at Object.e [as invoke] (http://127.0.0.1:8050/sitestatic/js/angular.min.js:36:335)
    at http://127.0.0.1:8050/sitestatic/js/angular.min.js:47:393
    at r (http://127.0.0.1:8050/sitestatic/js/angular.min.js:7:302)
    at Object.<anonymous> (http://127.0.0.1:8050/sitestatic/js/angular.min.js:47:360) angular.min.js:101

有人知道如何解决这个问题吗?我刚刚关注了this guide关于如何使用 AngularJS 处理点击事件,但似乎对我不起作用。

最佳答案

如果您只需要捕获 on-node-click 指令所附加的元素的特定子元素的点击,则可以在指令定义中将点击监听器附加到该元素,并使用 jQuery 的 .on() 中可选的 selector 参数方法来过滤您想要的子元素。您根本不需要处理 $document

所以你的指令看起来像这样:

.directive('onNodeClick', ['$parse', function ($parse) {    
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
      var scopeExpresssion = attrs.onNodeClick, // gets string 'getNodeTitle($event)' from element attribute            
          invoker = $parse(scopeExpresssion); // compile string into a function

      // listen for clicks on .node child elements
      element.on('click', '.node', function (e) {
        // wrap the function invocation in scope.$apply() so angular knows about it
        scope.$apply(function () {
          invoker(scope, { $event: e });
        });
      });
    }
  };
}]);

这是一个fiddle .

但是,如果您确实需要像该文章所讨论的那样捕获文档节点上的单击事件,则只需将 $document 注入(inject)您的指令并将单击监听器附加到该指令,而不是到您的指令所在的元素。

在这种情况下,您的指令将如下所示:

.directive('onNodeClick', ['$document', '$parse', function ($document, $parse) {    
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
      var scopeExpresssion = attrs.onNodeClick, // gets string 'getNodeTitle($event)' from element attribute            
          invoker = $parse(scopeExpresssion); // compile string into a function

      // listen for clicks on all .node elements within document
      $document.on('click', '.node', function (e) {
        // wrap the function invocation in scope.$apply() so angular knows about it
        scope.$apply(function () {
          invoker(scope, { $event: e });
        });
      });
    }
  };
}]);

关于javascript - AngularJS - 处理现有 DOM 元素上的点击事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26884510/

相关文章:

jquery - 使用angularjs从上到下为div设置动画

javascript - Angularjs:将 JSON 对象转换为键、值对

javascript - 在我的服务工厂中,我查找一个大型数据集 - 我想保留它并检查它是否存在以避免再次调用它

javascript - [React.js]尝试导入错误: './registerServiceWorker' does not contain a default export (imported as 'registerServiceWorker' )

javascript - 在 angularjs 中搜索和过滤多个模型

javascript - AngularJS 指令传递点击操作或执行 ui-router 状态更改

javascript - Angular 在使用 jq append 方法时是否编译指令?

javascript - 为什么 React 会针对具有由 React 管理的子项的 contentEditable 组件发出警告?

javascript - Angular js 在初始中间件身份验证后获取用户

javascript - 在其中也有链接的表行中使用 onClick