Re: [AngularJS] scope.$render vs ngModel.$watch in directive

5,221 views
Skip to first unread message

Peter Bacon Darwin

unread,
Dec 17, 2012, 5:03:05 AM12/17/12
to ang...@googlegroups.com
I would say the $render is more performant since it doesn't create yet another watch listener to run on each digest - but it is marginal.
Pete


On 17 December 2012 05:57, <finish...@yahoo.com> wrote:
Hello again, guys :)

I seem to be able to reproduce the same behavior using two different approaches in my directive:

ngModel.$render = function() {
  //do stuff
};

where ngModel is the fourth parameter passed to my linking function,

and

scope.$watch(attr.ngModel, function(){
//do stuff   
});

where scope and attr are the first and third parameter passed to my linking function, respectively.

I was wondering which one of these is the better solution performance-wise.

Arsen.


--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en-US.
 
 

finish...@yahoo.com

unread,
Dec 17, 2012, 5:11:36 AM12/17/12
to ang...@googlegroups.com
Hey,

That was my impression as well...

Blunder in the title btw, but you know what I meant.


Arsen.

finish...@yahoo.com

unread,
Dec 20, 2012, 10:24:15 PM12/20/12
to ang...@googlegroups.com
After some time, I noticed it's actually not the same.

Using $render in my directive, when I click on a checked checkbox to uncheck it, the first click is always ignored. Nothing happens to the view or the model. After that, each subsequent click does what you'd expect.

Whereas with $watch, it works straight away.

Interesting...


Arsen.

On Monday, December 17, 2012 11:03:05 AM UTC+1, Peter Bacon Darwin wrote:

Peter Bacon Darwin

unread,
Dec 21, 2012, 1:40:49 AM12/21/12
to ang...@googlegroups.com
Can you put up a demo?  It might be a bug.

finish...@yahoo.com

unread,
Dec 22, 2012, 2:44:33 PM12/22/12
to ang...@googlegroups.com
I'll try to make one tomorrow.


Arsen.

finish...@yahoo.com

unread,
Dec 26, 2012, 4:00:14 AM12/26/12
to ang...@googlegroups.com

It's ugly (like any plunker) and I didn't manage to get the checkboxes to render, but just click on the empty space next to the label and it will work.

To explain in detail: I am using uniform.js to create my custom uniform checkboxes via an angular directive. In this plunker, I created two different directives: the first one uses $render to keep track of state changes while the other one uses $watch.

The bug is the following: If you click on the first checkbox (the one that uses $render), the first time it will be ignored while each subsequent click will work as expected. The second checkbox uses $watch and works immediately.

This seems to happen only when using uniform.js.


Let me know what you think...


Arsen.

Peter Bacon Darwin

unread,
Dec 26, 2012, 5:07:52 AM12/26/12
to ang...@googlegroups.com
Hmm.  It seems from this http://plnkr.co/edit/cYei2K4zmX2as6vpWAmG?p=preview that $render is only ever called once, which doesn't seem to make sense for me as I thought it was called whenever the model changes.

finish...@yahoo.com

unread,
Dec 26, 2012, 5:40:37 AM12/26/12
to ang...@googlegroups.com
So it seems that $render executes on the first click and nothing actually happens. After that, the $render function is ignored. Which leads me to believe that $render was not meant to be used in this way. The documentation is very vague regarding this, so I would appreciate if someone could shed light on this. But what's confusing me now is that, going by this example http://plnkr.co/edit/XwuyXuGcPnRZsynGvWjZ?p=preview , it seems that $watch isn't required either...


Arsen.

finish...@yahoo.com

unread,
Dec 26, 2012, 5:59:57 AM12/26/12
to ang...@googlegroups.com, finish...@yahoo.com
But in ng-repeat it won't work without $watch. All the checkboxes would initialize unchecked regardless of the model. Unfortunately I can't demonstrate that on the plunker, since the checkboxes are not being drawn for some reason (maybe the css requires some images...)

Peter Bacon Darwin

unread,
Dec 27, 2012, 6:02:46 AM12/27/12
to ang...@googlegroups.com
Ok, so here is the deal.  $render is only called when the model value is updated "programmatically".  I.E. When you click on the check box it updates the model via the $parsers but the other direction ($formatters and $render) are not triggered.  You can see this here: http://plnkr.co/edit/XpkrFoHa8XCzIr51Bcbb?p=preview.  Also, I believe that when you set your own $render function, it hid the checkbox directive's $render function, which is supposed to update the value of the check box.

In your case I would move your code changes to the $formatters and $parsers so that it gets called in either direction: http://plnkr.co/edit/Cu3wDjoHgQV3xgVFPDGt?p=preview.

Pete

finish...@yahoo.com

unread,
Dec 27, 2012, 7:50:19 AM12/27/12
to ang...@googlegroups.com
I see. So the $render function cannot be extended like $parsers and $formatters.

What about $watch vs using $formatters and $parsers ? It seems to me now that using $watch here could be an overkill. Or not?


Arsen.

Peter Bacon Darwin

unread,
Dec 27, 2012, 8:46:22 AM12/27/12
to ang...@googlegroups.com
ngModel already watches the model and calls through the $formatters and $render when the model changes.
It calls the $parsers and updates the model when $setViewValue is called.

So I think you are right that you don't need to use $watch yourself and in fact $parsers and $formatters are better positioned for dealing with this kind of thing.

You can extend $render but if another directive is also using $render then there is a possibility, as in this case, that one or other directive will overwrite the $render of the others.
You'll notice in one of my Plnkrs I called the oldRender as part of the new $render.

Pete

finish...@yahoo.com

unread,
Dec 27, 2012, 9:24:59 AM12/27/12
to ang...@googlegroups.com
Mhm. Thanks for clarifying!


Arsen.
Reply all
Reply to author
Forward
0 new messages