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 this 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 doesn't work for me.
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 });
});
});
}
};
}]);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.