问题描述:

I'm trying to capture a click event on a selection of existing DOM items using Angular:

here's the code:

<!--

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 );

}

);

after reloading the page, i have tis error in console:

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

Anyone has an idea of how to solve it? I just followed this guide on how to handle click events with AngularJS but it seems that doens't work for me.

Many thanks!

LuKe

网友答案:

If you just need to capture clicks on specific child elements of the element your on-node-click directive is attached to, you would, in your directive definition, attach the click listener to that element, and use the optional selector parameter in jQuery's .on() method to filter for just the child elements you want. You don't need to deal with $document at all.

So your directive would look like this:

.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 });
        });
      });
    }
  };
}]);

Here's a fiddle.

If, however, you really do need to capture click events on the document node like that article discusses, you just need to inject $document into your directive and attach the click listener to that instead of to the element that your directive is on.

In that case, your directive would look like this:

.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 });
        });
      });
    }
  };
}]);
相关阅读:
Top