AngularJS – setting focus to element using NON-ISOLATE directive-Collection of common programming errors

I know this question has been asked about 100 times (trust me, I’ve read them all), but I’m having trouble getting focus to go to an input box when the directive does NOT use isolate scope. The scope.$watch doesn’t fire when the backing data changes.

Why not just use the one with isolate scope, you ask? Well, my understanding is that you should ONLY use isolate scope if your directive has a template.

The only differences in the directives is:

// works
app.directive('doesFocus', function ($timeout) {
    return {
        scope: { trigger: '@doesFocus' },
        link: function (scope, element) {
            scope.$watch('trigger', function (value) {
              // sets focus
            }
            ...

// does not work, and in fact when I inspect attrs.doesNotFocus it is undefined
app.directive('doesNotFocus', function ($timeout) {
    return {
        scope: false,
        link: function (scope, element, attrs) {
            scope.$watch(attrs.doesNotFocus, function (value) {
              // sets focus
            }
            ...

I’m on week 3 of using Angular, so I must be missing some silly semantic issue.

Here is a fiddle illustrating my issue. http://jsfiddle.net/tpeiffer/eAFmJ/

EDIT

My actual problem was that my real code was like this (hazard of mocking the problem, you sometimes mask the real problem):


but because I was using a function, not a property, I was missing the required ticks


Making this change fixed the problem and my directive can still be like this:

scope.$watch(attrs.shouldFocus, focusCallback(newValue));

END EDIT

Thanks for helping me in my quest for angular excellence!

Thad

  1. Your bottom drawer was watching a function isDrawerOpen(), not a property.
    Change

       scope.$watch('isDrawerOpen()',...);
    

    to

       scope.$watch('toggleBottomDrawer',...);
    
  2. Remove {{}} from your HTML. So instead of:

    
    

    use

    
    

    Then it works with watching attrs.doesNotFocus:

    scope.$watch(attrs.doesNotFocus, function (value) {...} );
    

    Fiddle