retrieving ElementRef within an event handler

133 views
Skip to first unread message

Stéphane Ancelot

unread,
Feb 1, 2019, 10:29:49 AM2/1/19
to Angular and AngularJS discussion
Hi,
I have got to implement drag and drop in a svg d3js component.

the svg elements are created dynamically . 

I want to retrieve the transform attribute of the dragged element in the drag handler.

This would mean, I would need ElementRef of these dynamically allocated element.

I suppose , the solution needs ViewChildren ,  but I don't know how to implement it.

The elements are created using the following code :
 this.g = this.svg.selectAll(".dimension")
       
.data(dimensions)
       
.enter().append("g")
       
.attr("class", "dimension")

       
.attr("transform", function(d) { return "translate(0," + _this.y(d.id) + ")"; })

Regards

Sander Elias

unread,
Feb 2, 2019, 12:42:01 AM2/2/19
to Angular and AngularJS discussion
Hi Stephane,

A dom event has a reference to its elements already, why can't you use those?

Regards
Sander

Stéphane Ancelot

unread,
Feb 4, 2019, 3:01:10 AM2/4/19
to Angular and AngularJS discussion
Hi,

I suppose that will depend on the way we setup the drag handler. two cases; first one  is setted up like this :

 
this.g = this.svg.selectAll(".dimension")
       
.data(dimensions)
       
.enter().append("g")

       
.attr("id","toto")

       
.attr("class", "dimension")
       
.attr("transform", function(d) { return "translate(0," + _this.y(d.id) + ")"; })

       
.call(d3.drag()

         
.on("start",(d, i) => this.dragstarted(d,i))
         
.on("drag",(d, i) => this.dragstarted(d,i))
         
.on("end", (d, i) => this.dragended(d, i)));


In this case, the dragstarted func will receive d as the dimension data associated to the g element.(not a dom event ...) 
and this keyword is pointing the whole component class. 

following the next example, I can receive the dom event target :-), but am unable to access the component class :-( , so unable to access some useful methods in the clas component:
 this.g = this.svg.selectAll(".dimension")
       
.data(dimensions)
       
.enter().append("g")

       
.attr("id","toto")

       
.attr("class", "dimension")
       
.attr("transform", function(d) { return "translate(0," + _this.y(d.id) + ")"; })

       
.call(d3.drag()
         
.on("start",this.dragstarted)
         
.on("drag", this.dragged)
         
.on("end", this.dragended));

Sander Elias

unread,
Feb 4, 2019, 5:35:31 AM2/4/19
to Angular and AngularJS discussion

Hi Stephane,

Try normal functions instead of arrow functions

 .on("start", function(d, i) {this.dragstarted(d,i)})

This will give you a workable this.

or

          .on("start",this.dragstarted.bind(this))

And this will make sure the function is bound to the class, I think this your best option

Regards
Sander

Stéphane Ancelot

unread,
Feb 5, 2019, 4:13:49 AM2/5/19
to Angular and AngularJS discussion
I finally ended as follow :


since this keyword can not be accessible to access component class methods from the event handler, I had to keep  a reference to it .

const reference = this;
xstart
: number;


 
function dragstarted(d)
 
{
.. reference.xstart = d3.event.x;
 
}
....


d3
... .on("start",dragstarted)



Le vendredi 1 février 2019 16:29:49 UTC+1, Stéphane Ancelot a écrit :
Reply all
Reply to author
Forward
0 new messages