Directives from Scratch: Slides from AngularJS DC Meetup

You can find the associated (poorly-documented) demo files on github. And here are the slides from my previous ‘From Scratch’ Meetup, which was an introduction to the rest of Angular.

Tagged , , , , , ,

5 thoughts on “Directives from Scratch: Slides from AngularJS DC Meetup

  1. JM says:

    Two questions in regards to a directive communicating with its host application:

    1 – You mention the best way of doing is via the use of $watch and AngularJS Events. Would a simple event driven model be better since it allows you to avoid any performance costs of using $watch?

    2 – Would it be possible (and does it even make sense) to have the directive expose a Promise on the Scope that the host application can use for communication?

    Thanks for the highly informative slide and keep up the good work on the BLOG, love reading it!

    • XMLilley says:

      You mention AngularJS Events, but then contrast them with ‘a simple event-driven model’. Was that intentional? It’s certainly possible to substitute something like a pub-sub system for Angular’s event system if you’re looking to consume the fewest possible cycles, and that may be a great solution for a post-iteration refactor in a performance-driven application. But you may sacrifice reusability and maintainability. YMMV.

      In general, there are cases where $watch is necessary, in spite of the overhead (just make sure watchers are fast and idempotent); and cases where Angular events are preferable. They’re both important things you want to have in your toolkit, so you can match the needs of the context. $watch, in general, is a tool for ensuring that you don’t overlook any possible source of mutations to a property, particularly during the early iteration of your application. Angular’s events similarly allow you to $broadcast throughout the system and ensure you won’t miss any possible consumers that you forgot about, and to create new consumers with minimal fuss.

      Promises too, are an awesome pattern. In fact, check out my other posts and you’ll see I delivered the talk on promises at ng-conf. They’re certainly a legitimate communications pathway. In the classic model of a directive as a reusable component, exposing a scope property that’s consumed by other scopes may be problematic for ensuring your code is decoupled from context to the greatest extent possible. Events or pub-sub will grant you greater flexibility that way. That said, the other model of a directive is simply as an encapsulated chunk of content and logic. If you wanted to bind that chunk to a particular context via a promise, that could certainly work well. Just keep in mind that unless your browser context supports native promises, any javascript promise system is going to be running $timeouts that may possibly be *less* efficient than $watch (if you’re really counting to the last cycle). It’ll certainly be less efficient than broadcasting an event, even on a complex scope-tree. Check out the angular-ui modal for an excellent example of where promises are a perfect fit, as a capstone for the modal’s lifecycle.

      “Premature optimization is the root of all evil.” I’d consider that when sweating whether Angular events are efficient enough for you. If you can build your prototype, prove your business-case, find customers, and become so successful you have to worry about questions of scale, that’s the time to worry about shaving 10 cycles with a custom communications system. Until then, Angular events are awesome, fast to build, and super-maintainable. And as long as you are attentive to the question of how often your $digest’s are firing, even $watch is generally worth a couple extra cycles. (Actually, you can expect $watch to implement native ES6 watchers in Angular 2.0, making the performance question for standard CRUD apps moot in most cases.)

      • JM says:

        Thank you for the very informative answer and that’s correct, I was contrasting a simple event call-back model vs using AngularJS Events and your response answered that perfectly.

        Last question; if you did use Promises (even though they are less efficient as you mentioned for this use-case), wouldn’t you also run into a problem where if using a reusable component in the form of a Directive, if you expose a promise on the scope to correspond to a particular event, you can only resolve that Promise once inside of the directive right? In which case, if the Directive fired off that event again, you wouldn’t be able to resolve that Promise again right?

        It seems to me that although Promises are great, they are not the best fit for communication between a Directive and its host application. It seems that either using $watch or event call-backs make more sense for this scenario.

        Btw, my team and I actually watched your Promise video and is actually how I found your BLOG. Fantastic content and is a big reason as to why we are now looking into Promises so much.

  2. XMLilley says:

    Coolness. Always glad to hear somebody liked that presentation!

    If you wanted to be able to resolve the Promise from outside of the Directive that created it, you could expose the Deferred object that owns the promise. But it does indeed sound like events might be a better fit, because you want a round-trip lifecycle with communication back and forth between contexts. It would be both more flexible and better separation of concerns.

    On the question of multiple resolutions: I’d need to see more about the use-case. But part of the point of a promise is that you don’t need to *resolve* the promise multiple times, but you can rather .then() it as many times as you want, and you get the same behavior whether it’s the first time or the 10th; pre-resolution or post-. So, I’d expose the Promise and then all the consumers would simply chain contingent handlers from it, while you allow the originating context to handle the resolution.

    I’ve seen implementations that combine events and promises to good effect, where the payload of the events is actually a reference to a promise. You can fire multiple events that all carry the same promise reference with them if you want, or different promises that represent various operations. Each time, you can query the resolution status of the promise, .then() it, or anything else you like, but without needing to know anything further about the originating context. Hence, my thesis that promises make a neat “universal API for uncertainty.”

    • JM says:

      Very interesting, especially about payloads of Events being a reference to a Promise. Thanks for the thoughtful answers, you’ve answered a lot of questions my team and I have had for a couple weeks now!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: