Implementing a highlight-on-change directive

1,025 views
Skip to first unread message

Saurabh Nanda

unread,
Jan 26, 2013, 12:58:13 PM1/26/13
to ang...@googlegroups.com
Hi,

Angular newbie here. I'm trying to implement a generic "highlight-on-change" directive that I can use to visually highlight DOM elements that have changed AND require user attention [1]. I would like some feedback on whether http://plnkr.co/edit/ojlxiYnLGbJPEbtIM2Z7 is the most efficient way to do this? I'm especially concerned about the watch in element.html().

Thoughts?

[1] Possible use-case: the user creates a new line-item in an invoice and the total changes, which needs to be momentarily highlighted.

Saurabh.

Pawel Kozlowski

unread,
Jan 26, 2013, 1:19:46 PM1/26/13
to ang...@googlegroups.com
Hi!

On Sat, Jan 26, 2013 at 6:58 PM, Saurabh Nanda <saurab...@gmail.com> wrote:
> I'm especially concerned about the watch in element.html().

You are concerned for a good reason since this is definitively
something we should _not_ be doing. The reason is simple: performance.
DOM access is an order of magnitude slower as compared to a watch
setup on a JavaScript object. And watches are executed often in
AngularJS, very often.

Your directive should be based on a model. Maybe the way to go forward
would be to write a custom version of the interpolate directive ({{
}})?

Cheers,
Pawel

--
Question? Send a fiddle
(http://jsfiddle.net/pkozlowski_opensource/Q2NpJ/) or a plunk
(http://plnkr.co/)
Need help with jsFiddle? Check this:
http://pkozlowskios.wordpress.com/2012/08/12/using-jsfiddle-with-angularjs/

Looking for UI widget library for AngularJS? Here you go:
http://angular-ui.github.com/

Saurabh Nanda

unread,
Jan 26, 2013, 1:42:47 PM1/26/13
to ang...@googlegroups.com

Your directive should be based on a model. Maybe the way to go forward
would be to write a custom version of the interpolate directive ({{
}})?


Another approach could be to pass a (model-based) expression to the highlight-on-change directive. The directive could set-up a watch on that expression and highlight the entire element upon change. Is that better?

How does one write a custom version of the interpolate directive? And how will that help?

Saurabh.
--
http://www.saurabhnanda.com

Pawel Kozlowski

unread,
Jan 26, 2013, 1:50:25 PM1/26/13
to ang...@googlegroups.com
Hi!

On Sat, Jan 26, 2013 at 7:42 PM, Saurabh Nanda <saurab...@gmail.com> wrote:
>

> Another approach could be to pass a (model-based) expression to the
> highlight-on-change directive. The directive could set-up a watch on that
> expression and highlight the entire element upon change. Is that better?

The only problem here is that you would have to repeat your model
expression - once for the highlight watcher and another one to
actually render data.
On top of this it would also double number of watches.

> How does one write a custom version of the interpolate directive? And how
> will that help?

Well, this could be as simple as <span my-interpolate="expr"></span>.

The only problem here is how to select an element to be highlighted...
Assuming that we are always going to highlight a parent is probably
too restrictive...

Not sure I've got a perfect solution here (errr, I'm quite sure I
_don't_ have a perfect solution :-))

Cheers,
Pawel

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

Joshua Miller

unread,
Jan 26, 2013, 2:09:32 PM1/26/13
to angular
Hello!

If you're looking at changes, I assume you care about changes in the model (like your invoice total example) rather than changes in the DOM. So why not have highlightOnChange watch an expression and highlight *itself* on change: http://plnkr.co/edit/FFBhPIRuT0NA2DZhtoAD?p=preview (sorry, I had to re-create the Plunker as the service was not cooperating).

Josh


To unsubscribe from this group, send email to angular+u...@googlegroups.com.

Saurabh Nanda

unread,
Jan 26, 2013, 2:17:51 PM1/26/13
to ang...@googlegroups.com
If you're looking at changes, I assume you care about changes in the model (like your invoice total example) rather than changes in the DOM. So why not have highlightOnChange watch an expression and highlight *itself* on change: http://plnkr.co/edit/FFBhPIRuT0NA2DZhtoAD?p=preview (sorry, I had to re-create the Plunker as the service was not cooperating).

 Thanks for the plunker. Conceptually, is this different from passing an expression to the directive, which it then sets up a watch on?

Saurabh.
--
http://www.saurabhnanda.com

Saurabh Nanda

unread,
Jan 26, 2013, 2:19:11 PM1/26/13
to ang...@googlegroups.com
The only problem here is that you would have to repeat your model
expression - once for the highlight watcher and another one to
actually render data.
On top of this it would also double number of watches.

Hang on, is this true? If I watch the exact same expression 10 times, does that really set-up 10 different watches? Is the expression evaluated 10 times in each digest loop? What if it's the exact same binding in 10 spots in the template?

Saurabh.
--
http://www.saurabhnanda.com

Pawel Kozlowski

unread,
Jan 26, 2013, 2:31:04 PM1/26/13
to ang...@googlegroups.com
On Sat, Jan 26, 2013 at 8:19 PM, Saurabh Nanda <saurab...@gmail.com> wrote:

> Hang on, is this true? If I watch the exact same expression 10 times, does
> that really set-up 10 different watches? Is the expression evaluated 10
> times in each digest loop? What if it's the exact same binding in 10 spots
> in the template?

Hmm, good point! Actually, _I don't know_.... Will try to check it later on.
Thnx for the wake up call, I don;t know why I've assumed this without checking!

Cheers,
Pawel

Joshua Miller

unread,
Jan 26, 2013, 2:34:28 PM1/26/13
to angular
Hello!

Conceptually, using attrs.$observe is different than setting up a $watch because it doesn't require the directive to either access the parent scope or create a new scope.

Josh


On Sat, Jan 26, 2013 at 11:31 AM, Pawel Kozlowski <pkozlowski...@gmail.com> wrote:
--
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.
Reply all
Reply to author
Forward
0 new messages