I have created a list of items with an object inside my controller
$scope.devices = [
{"id": 0, "name": "sw", "class": 'sw' },
{"id": 1, "name": "mlr", "class": 'mlr'},
{"id": 2, "name": "lvm", "class": 'lvm'},
{"id": 3, "name": "ltc", "class": 'ltc'},
{"id": 4, "name": "fr", "class": 'fr'},
{"id": 5, "name": "cap", "class": 'cap'}
];
and ng-repeat in my HTML
<li ng-repeat="device in devices" ng-click="selected(device.id)"></li>
I can keep track of an item that is clicked with $scope.selected
bound to my ng-click
that's basic.
However, what about later on, in a directive when an even fires? How can I collect information from the element? Specifically the original object id it came from?
// A device is grabbed
ums.directive('draggable', function (){
return function ($scope, element, attr){
// restrict: "A",
// link: function (){}
var el = element[0];
el.draggable = true;
el.addEventListener(
'dragstart',
function(e) {
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('Text', this.id);
this.classList.add('drag');
// when this event is fired I want the corresponding object id from $scope.devices
console.log(el.$scope.device.id); // my first inclination
return false;
},
false
);
}
})
The ng-repeat
directive creates a scope for each line that it adds to the DOM. On each scope will be special properties set by ng-repeat
.
From the Docs:
The ngRepeat
directive instantiates a template once per item from a collection. Each template instance gets its own scope, where the given loop variable is set to the current collection item, and $index
is set to the item index or key.
The scope inherits from $parent
scope. In your directive's linking function, you can use scope.$parent.devices[scope.$index]
to access the original but it is also on the local scope as well.
For more information see the AngularJS ngRepeat API Reference.
Update with example
This example shows the directive getting the $index and also emitting a custom event for the controller to use.
The directive
ums.directive('draggable', function (){
function postLinkFn (scope, elem, attr){
console.log("instantiating directive");
elem.prop('draggable', true);
elem.on ('dragstart',
function(e) {
elem.addClass('drag');
console.log("dragstart index =", scope.$index);
//emit event for controller
scope.$emit("umsDragstart", e);
return false;
}
);
}
return postLinkFn;
})
In the controller
$scope.$on("umsDragstart", function ($event, rawEvent){
console.log($event);
console.log(rawEvent.x, rawEvent.y);
console.log("umsDragstart id =", $event.targetScope.device.id);
});
Notice that the example uses jqLite
methods on the elem
parameter of the postLinkFn
. Those methods are documented in the AngularJS angular.element API Reference.
The $on
and $emit
methods are documented in the AngularJS $rootScope.scope API Reference - $on and API Reference - $emit.
If you are using the directive inside the controller in which selected()
function is written the you can assign the id to some scope variable and access it in directive.
else if you are using the directive inside a ng-repeat
then you can set custom scope variable for directive and pass the current id to it.
or else give away a code example