Как установить фокус на поле ввода?

Что такое способ Angular, чтобы установить фокус на поле ввода в AngularJS?

Более конкретные требования:

  • Когда открывается Modal, установите фокус на предопределенный <input> внутри этого модального файла.
  • Каждый раз <input> становится видимым (например, нажатием кнопки), установите фокус на нем.

Я попытался выполнить первое требование с помощью autofocus, но это работает только тогда, когда модаль открывается впервые и только в некоторых браузерах (например, в Firefox это не работает).

Любая помощь будет оценена.

Ответ 1

  • Когда модальный режим открыт, установите фокус на предопределенный <input> внутри этого модального файла.

Определите директиву и получите $watch свойство /trigger, чтобы он знал, когда нужно сфокусировать элемент:

Name: <input type="text" focus-me="shouldBeOpen">

app.directive('focusMe', ['$timeout', '$parse', function ($timeout, $parse) {
    return {
        //scope: true,   // optionally create a child scope
        link: function (scope, element, attrs) {
            var model = $parse(attrs.focusMe);
            scope.$watch(model, function (value) {
                console.log('value=', value);
                if (value === true) {
                    $timeout(function () {
                        element[0].focus();
                    });
                }
            });
            // to address @blesh comment, set attribute value to 'false'
            // on blur event:
            element.bind('blur', function () {
                console.log('blur');
                scope.$apply(model.assign(scope, false));
            });
        }
    };
}]);

Plunker

Тайм-аут $, кажется, необходим, чтобы дать модальное время для рендеринга.

'2'. Everytime <input> становится видимым (например, нажатием какой-либо кнопки), установите фокус на него.

Создайте директиву, по существу подобную той, что указана выше. Посмотрите на свойство scope, и когда оно станет истинным (установите его в обработчике ng-click), выполните element[0].focus(). В зависимости от вашего варианта использования вам может понадобиться или не понадобиться $timeout для этого:

<button class="btn" ng-click="showForm=true; focusInput=true">show form and
 focus input</button>
<div ng-show="showForm">
  <input type="text" ng-model="myInput" focus-me="focusInput"> {{ myInput }}
  <button class="btn" ng-click="showForm=false">hide form</button>
</div>

app.directive('focusMe', function($timeout) {
  return {
    link: function(scope, element, attrs) {
      scope.$watch(attrs.focusMe, function(value) {
        if(value === true) { 
          console.log('value=',value);
          //$timeout(function() {
            element[0].focus();
            scope[attrs.focusMe] = false;
          //});
        }
      });
    }
  };
});

Plunker


Обновление 7/2013. Я видел, как некоторые люди используют мои исходные директивы выделения, а затем имеют проблемы со встроенными полями ввода (т.е. поле ввода в модальном). Директива, не имеющая новых возможностей (или, возможно, новый охват ребенка), должна облегчить боль. Поэтому выше я обновил ответ, чтобы не использовать области выделения. Ниже приведен оригинальный ответ:

Оригинальный ответ для 1., используя область выделения:

Name: <input type="text" focus-me="{{shouldBeOpen}}">

app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '@focusMe' },
    link: function(scope, element) {
      scope.$watch('trigger', function(value) {
        if(value === "true") { 
          $timeout(function() {
            element[0].focus(); 
          });
        }
      });
    }
  };
});

Plunker.

Оригинальный ответ для 2., используя область выделения:

<button class="btn" ng-click="showForm=true; focusInput=true">show form and
 focus input</button>
<div ng-show="showForm">
  <input type="text" focus-me="focusInput">
  <button class="btn" ng-click="showForm=false">hide form</button>
</div>

app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '=focusMe' },
    link: function(scope, element) {
      scope.$watch('trigger', function(value) {
        if(value === true) { 
          //console.log('trigger',value);
          //$timeout(function() {
            element[0].focus();
            scope.trigger = false;
          //});
        }
      });
    }
  };
});

Plunker.

Поскольку нам нужно reset свойство trigger/focusInput в директиве, '=' используется для двусторонней привязки данных. В первой директиве "@" было достаточно. Также обратите внимание, что при использовании "@" мы сравниваем значение триггера с "истинным", так как @всегда выводит строку.

Ответ 2

(EDIT: я добавил обновленное решение ниже этого объяснения)

Марк Райкок - человек... и его ответ - правильный ответ, но у него есть дефект (извините Марк)...

... Попробуйте использовать логическое значение, чтобы сфокусироваться на входе, затем размывайте вход, затем попробуйте использовать его, чтобы снова сфокусировать вход. Это не сработает, если вы не reset с логическим значением false, затем $digest, а затем reset вернемся к true. Даже если вы используете сравнение строк в своем выражении, вам придется изменить строку на что-то еще, $digest, а затем изменить ее. (Это было обработано обработчиком размытия).

Поэтому я предлагаю это альтернативное решение:

Использовать событие, забытую функцию Angular.

JavaScript любит события в конце концов. События по своей сути слабо связаны, и даже лучше, вы избегаете добавлять еще $watch к вашему $digest.

app.directive('focusOn', function() {
   return function(scope, elem, attr) {
      scope.$on(attr.focusOn, function(e) {
          elem[0].focus();
      });
   };
});

Итак, теперь вы можете использовать его следующим образом:

<input type="text" focus-on="newItemAdded" />

а затем в любом месте вашего приложения...

$scope.addNewItem = function () {
    /* stuff here to add a new item... */

    $scope.$broadcast('newItemAdded');
};

Это потрясающе, потому что вы можете делать всевозможные вещи с чем-то подобным. Во-первых, вы можете связать события, которые уже существуют. С другой стороны, вы начинаете делать что-то умное, если разные части вашего приложения публикуют события, на которые могут подписаться другие части вашего приложения.

Во всяком случае, этот тип вещей кричит "событие, вызванное" мне. Я думаю, что в качестве разработчиков Angular мы стараемся очень тяжело забивать привязанные к форме области привязки в дыры формы событий.

Это лучшее решение? Не знаю. Это решение.


Обновленное решение

После комментария @ShimonRachlenko ниже я изменил свой способ сделать это немного. Теперь я использую комбинацию сервиса и директивы, которая обрабатывает событие "за кадром":

Кроме того, это тот же самый принцип, о котором говорилось выше.

Вот демонстрационный демонстрационный план

Использование

<input type="text" focus-on="focusMe"/>
app.controller('MyCtrl', function($scope, focus) {
    focus('focusMe');
});

Источник

app.directive('focusOn', function() {
   return function(scope, elem, attr) {
      scope.$on('focusOn', function(e, name) {
        if(name === attr.focusOn) {
          elem[0].focus();
        }
      });
   };
});

app.factory('focus', function ($rootScope, $timeout) {
  return function(name) {
    $timeout(function (){
      $rootScope.$broadcast('focusOn', name);
    });
  }
});

Ответ 3

Я нашел некоторые другие ответы слишком сложными, когда все, что вам действительно нужно, это

app.directive('autoFocus', function($timeout) {
    return {
        restrict: 'AC',
        link: function(_scope, _element) {
            $timeout(function(){
                _element[0].focus();
            }, 0);
        }
    };
});

используется

<input name="theInput" auto-focus>

Мы используем таймаут, чтобы позволить вещам в dom render, даже несмотря на то, что он равен нулю, он, по крайней мере, ждет этого - таким образом, это работает в модалах и еще что-то еще

Ответ 5

Вы также можете использовать функцию jqlite, встроенную в angular.

angular.element('.selector').trigger('focus');

Ответ 6

Это хорошо работает и angular способ фокусировки управления вводом

angular.element('#elementId').focus()

Это хотя и не чистый angular способ выполнения задачи, но синтаксис следует за стилем angular. JQuery играет роль косвенно и напрямую обращается к DOM, используя angular (jQLite = > JQuery Light).

При необходимости этот код можно легко поместить в простую директиву angular, где элемент доступен непосредственно.

Ответ 7

Я не думаю, что $timeout - это хороший способ сфокусировать элемент на создании. Вот метод с использованием встроенной функции angular, выкопанной из мрачной глубины документов angular. Обратите внимание, как атрибут "link" можно разделить на "pre" и "post", для функций предварительной ссылки и пост-ссылки.

Рабочий пример: http://plnkr.co/edit/Fj59GB

// this is the directive you add to any element you want to highlight after creation
Guest.directive('autoFocus', function() {
    return {
        link: {
            pre: function preLink(scope, element, attr) {
                console.debug('prelink called');
                // this fails since the element hasn't rendered
                //element[0].focus();
            },
            post: function postLink(scope, element, attr) {
                console.debug('postlink called');
                // this succeeds since the element has been rendered
                element[0].focus();
            }
        }
    }
});
<input value="hello" />
<!-- this input automatically gets focus on creation -->
<input value="world" auto-focus />

Документация по полной системе AngularJS: https://docs.angularjs.org/api/ng/service/$compile

Ответ 8

Я недавно написал директиву о двухстороннем связывании фокуса, как и модель.

Вы можете использовать директиву focus следующим образом:

<input focus="someFocusVariable">

Если вы someFocusVariable переменной сферы true в любом месте вашего контроллера, вход сфокусироваться. И если вы хотите "размыть" свой ввод, тогда для someFocusVariable можно установить значение false. Это похоже на первый ответ Марка Райкока, но с двусторонним связыванием.

Вот директива:

function Ctrl($scope) {
  $scope.model = "ahaha"
  $scope.someFocusVariable = true; // If you want to focus initially, set this to true. Else you don't need to define this at all.
}

angular.module('experiement', [])
  .directive('focus', function($timeout, $parse) {
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {
          scope.$watch(attrs.focus, function(newValue, oldValue) {
              if (newValue) { element[0].focus(); }
          });
          element.bind("blur", function(e) {
              $timeout(function() {
                  scope.$apply(attrs.focus + "=false"); 
              }, 0);
          });
          element.bind("focus", function(e) {
              $timeout(function() {
                  scope.$apply(attrs.focus + "=true");
              }, 0);
          })
      }
    }
  });

Использование:

<div ng-app="experiement">
  <div ng-controller="Ctrl">
    An Input: <input ng-model="model" focus="someFocusVariable">
    <hr>
        <div ng-click="someFocusVariable=true">Focus!</div>  
        <pre>someFocusVariable: {{ someFocusVariable }}</pre>
        <pre>content: {{ model }}</pre>
  </div>
</div>

Вот скрипка:

http://fiddle.jshell.net/ubenzer/9FSL4/8/

Ответ 9

Вот мое оригинальное решение:

plunker

var app = angular.module('plunker', []);
app.directive('autoFocus', function($timeout) {
    return {
        link: function (scope, element, attrs) {
            attrs.$observe("autoFocus", function(newValue){
                if (newValue === "true")
                    $timeout(function(){element[0].focus()});
            });
        }
    };
});

И HTML:

<button ng-click="isVisible = !isVisible">Toggle input</button>
<input ng-show="isVisible" auto-focus="{{ isVisible }}" value="auto-focus on" />

Что он делает:

Он фокусирует ввод, когда он становится видимым с помощью ng-show. Здесь нет использования $watch или $.

Ответ 10

Для тех, кто использует Angular с плагином Bootstrap:

http://angular-ui.github.io/bootstrap/#/modal

Вы можете подключиться к обещанию opened модального экземпляра:

modalInstance.opened.then(function() {
        $timeout(function() {
            angular.element('#title_input').trigger('focus');
        });
    });

modalInstance.result.then(function ( etc...

Ответ 11

Вместо создания собственной директивы можно просто использовать функции javascript для достижения фокуса.

Вот пример.

В html файле:

<input type="text" id="myInputId" />

В файле javascript, например, в контроллере, где вы хотите активировать фокус:

document.getElementById("myInputId").focus();

Ответ 12

Не воскрешать зомби или подключить мою собственную директиву (хорошо, что именно я делаю):

https://github.com/hiebj/ng-focus-if

http://plnkr.co/edit/MJS3zRk079Mu72o5A9l6?p=preview

<input focus-if />

(function() {
    'use strict';
    angular
        .module('focus-if', [])
        .directive('focusIf', focusIf);

    function focusIf($timeout) {
        function link($scope, $element, $attrs) {
            var dom = $element[0];
            if ($attrs.focusIf) {
                $scope.$watch($attrs.focusIf, focus);
            } else {
                focus(true);
            }
            function focus(condition) {
                if (condition) {
                    $timeout(function() {
                        dom.focus();
                    }, $scope.$eval($attrs.focusDelay) || 0);
                }
            }
        }
        return {
            restrict: 'A',
            link: link
        };
    }
})();

Ответ 13

Мне было полезно использовать общее выражение. Таким образом, вы можете делать такие вещи, как автоматическое перемещение фокуса, когда текст ввода действителен.

<button type="button" moo-focus-expression="form.phone.$valid">

Или автоматически сфокусируйтесь, когда пользователь завершит поле с фиксированной длиной

<button type="submit" moo-focus-expression="smsconfirm.length == 6">

И, конечно, фокус после загрузки

<input type="text" moo-focus-expression="true">

Код для директивы:

.directive('mooFocusExpression', function ($timeout) {
    return {
        restrict: 'A',
        link: {
            post: function postLink(scope, element, attrs) {
                scope.$watch(attrs.mooFocusExpression, function (value) {

                    if (attrs.mooFocusExpression) {
                        if (scope.$eval(attrs.mooFocusExpression)) {
                            $timeout(function () {
                                element[0].focus();
                            }, 100); //need some delay to work with ng-disabled
                        }
                    }
                });
            }
        }
    };
});

Ответ 14

Во-первых, официальный способ сделать акцент сделан на дорожной карте для 1.1. Тем временем вы можете написать директиву, чтобы реализовать настройку фокуса.

Во-вторых, для установки фокуса на элемент после того, как он стал видимым, в настоящее время требуется обходное решение. Просто задержите вызов фокуса элемента() с помощью $timeout.

Поскольку тот же самый контроллер изменяет -DOM-проблему для фокуса, размытия и выбора, я предлагаю иметь директиву ng-target:

<input type="text" x-ng-model="form.color" x-ng-target="form.colorTarget">
<button class="btn" x-ng-click="form.colorTarget.focus()">do focus</button>

Angular здесь: http://goo.gl/ipsx4, и более подробная информация приведена здесь: http://goo.gl/4rdZa

Следующая директива создаст функцию .focus() внутри вашего контроллера, как указано вашим атрибутом ng-target. (Он создает также .blur() и .select().) Демо: http://jsfiddle.net/bseib/WUcQX/

Ответ 15

Если вам просто нужен простой фокус, который контролируется ng-click.

Html:

<input ut-focus="focusTigger">

<button ng-click="focusTrigger=!focusTrigger" ng-init="focusTrigger=false"></button>

Директива

'use strict'

angular.module('focus',['ng'])
.directive('utFocus',function($timeout){
    return {
        link:function(scope,elem,attr){
            var focusTarget = attr['utFocus'];
            scope.$watch(focusTarget,function(value){
                $timeout(function(){
                    elem[0].focus();
                });
            });
        }
    }
});

Ответ 16

Простой, который хорошо работает с модалами:

.directive('focusMeNow', ['$timeout', function ($timeout)
{
    return {
        restrict: 'A',

        link: function (scope, element, attrs)
        {


            $timeout(function ()
            {
                element[0].focus();
            });



        }
    };
}])

Пример

<input ng-model="your.value" focus-me-now />

Ответ 17

Вы можете просто создать директиву, которая заставляет фокус на украшенный элемент на postLinking:

angular.module('directives')
.directive('autoFocus', function() {
    return {
        restrict: 'AC',
        link: function(_scope, _element) {
            _element[0].focus();
        }
    };
});

Затем в вашем html:

<input type="text" name="first" auto-focus/> <!-- this will get the focus -->
<input type="text" name="second"/>

Это будет работать для модалов и ng-if toggled элементов, а не для ng-show, поскольку postLinking происходит только при обработке HTML.

Ответ 18

У Марка и Блеста есть отличные ответы; однако у Марка есть недостаток, который указывает Блеш (помимо того, что он сложный для реализации), и я чувствую, что ответ Blesh имеет семантическую ошибку при создании службы, которая специально посылает запрос фокуса интерфейсу, когда действительно все, что ему нужно, - это способ задерживайте событие до тех пор, пока не будут прослушиваться все директивы.

Итак, вот что я в итоге сделал, который много крал от ответа Blesh, но сохраняет семантику события контроллера и отдельную службу "после загрузки".

Это позволяет легко подключаться к событию контроллера для других целей, кроме как просто фокусировки определенного элемента, а также позволяет налагать накладные расходы на функциональность "после загрузки", только если это необходимо, что может быть не во многих случаях.

Использование

<input type="text" focus-on="controllerEvent"/>
app.controller('MyCtrl', function($scope, afterLoad) {
  function notifyControllerEvent() {
      $scope.$broadcast('controllerEvent');
  }

  afterLoad(notifyControllerEvent);
});

Источник

app.directive('focusOn', function() {
   return function(scope, elem, attr) {
      scope.$on(attr.focusOn, function(e, name) {
        elem[0].focus();
      });
   };
});

app.factory('afterLoad', function ($rootScope, $timeout) {
  return function(func) {
    $timeout(func);
  }
});

Ответ 19

Это также можно использовать ngModelController. Работа с 1.6+ (не знаю со старыми версиями).

HTML

<form name="myForm">
    <input type="text" name="myText" ng-model="myText">
</form>

JS

$scope.myForm.myText.$$element.focus();

-

N.B.: В зависимости от контекста вам, возможно, придется перевернуть функцию тайм-аута.

N.B.²: При использовании controllerAs это почти то же самое. Просто замените name="myForm" на name="vm.myForm" и в JS, vm.myForm.myText.$$element.focus();.

Ответ 20

Возможно, самое простое решение в эпоху ES6.

Добавление следующей директивы liner делает атрибут "автофокусировки" HTML эффективным на Angular.js.

.directive('autofocus', ($timeout) => ({link: (_, e) => $timeout(() => e[0].focus())}))

Теперь вы можете просто использовать синтаксис автофокуса HTML5, например:

<input type="text" autofocus>

Ответ 21

Просто новичок здесь, но я не мог заставить его работать в ui.bootstrap.modal с этой директивой:

directives.directive('focus', function($timeout) {
    return {
        link : function(scope, element) {
            scope.$watch('idToFocus', function(value) {
                if (value === element[0].id) {
                    $timeout(function() {
                        element[0].focus();
                    });
                }
            });
        }
    };
});

а в методе $modal.open я использовал следующее выражение, чтобы указать элемент, в который нужно поместить фокус:

var d = $modal.open({
        controller : function($scope, $modalInstance) {
            ...
            $scope.idToFocus = "cancelaAteste";
    }
        ...
    });

на шаблоне у меня есть это:

<input id="myInputId" focus />

Ответ 22

Я редактирую директиву Mark Rajcok focusMe для работы с несколькими фокусами в одном элементе.

HTML:

<input  focus-me="myInputFocus"  type="text">

в контроллере AngularJs:

$scope.myInputFocus= true;

Директива AngulaJS:

app.directive('focusMe', function ($timeout, $parse) {
    return {
        link: function (scope, element, attrs) {
            var model = $parse(attrs.focusMe);
            scope.$watch(model, function (value) {
                if (value === true) {
                    $timeout(function () {
                        scope.$apply(model.assign(scope, false));
                        element[0].focus();
                    }, 30);
                }
            });
        }
    };
});

Ответ 23

Следующая директива сделала трюк для меня. Используйте тот же атрибут html автофокуса для ввода.

.directive('autofocus', [function () {
    return {
        require : 'ngModel',
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.focus();
        }
    };
}])

Ответ 24

Если вы используете modalInstance и имеете объект, вы можете использовать "then" для выполнения действий после открытия модального. Если вы не используете modalInstance и жестко закодированы для открытия модального, вы можете использовать это событие. Тайм-аут $не является хорошим решением.

Вы можете сделать (Bootstrap3):

$("#" + modalId).on("shown.bs.modal", function() {
    angular.element("[name='name']").focus();
});

В modalInstance вы можете посмотреть на библиотеку, как выполнить код после открытого модала.

Не используйте $timeout, как это, $timeout может быть 0, 1, 10, 30, 50, 200 или более, это будет зависеть от клиентского компьютера и процесс для открытия модального.

Не используйте $timeout, если метод подскажет вам, когда вы можете сфокусироваться;)

Я надеюсь, что эта помощь!:)

Ответ 25

Все предыдущие ответы не работают, если желаемый элемент фокусировки вводится в шаблон директивы. Следующая директива соответствует как элементам с простым элементом, так и директивой (я написал это в typescript). он принимает селектор для внутреннего фокусируемого элемента. если вам просто нужно сфокусировать элемент self - не отправляйте в директиву какой-либо параметр выбора:

module APP.Directives {

export class FocusOnLoadDirective implements ng.IDirective {
    priority = 0;
    restrict = 'A';

    constructor(private $interval:any, private $timeout:any) {

    }

    link = (scope:ng.IScope, element:JQuery, attrs:any) => {
        var _self = this;
        var intervalId:number = 0;


        var clearInterval = function () {
            if (intervalId != 0) {
                _self.$interval.cancel(intervalId);
                intervalId = 0;
            }
        };

        _self.$timeout(function(){

                intervalId = _self.$interval(function () {
                    let focusableElement = null;
                    if (attrs.focusOnLoad != '') {
                        focusableElement = element.find(attrs.focusOnLoad);
                    }
                    else {
                        focusableElement = element;
                    }
                    console.debug('focusOnLoad directive: trying to focus');
                    focusableElement.focus();
                    if (document.activeElement === focusableElement[0]) {
                        clearInterval();
                    }
                }, 100);

                scope.$on('$destroy', function () {
                    // Make sure that the interval is destroyed too
                    clearInterval();
                });

        });
    };

    public static factory = ():ng.IDirectiveFactory => {
        let directive = ($interval:any, $timeout:any) => new FocusOnLoadDirective($interval, $timeout);
        directive.$inject = ['$interval', '$timeout'];
        return directive;
    };
}

angular.module('common').directive('focusOnLoad', FocusOnLoadDirective.factory());

}

пример использования для простого элемента:

<button tabindex="0" focus-on-load />

пример использования для внутреннего элемента (обычно для динамического вложенного элемента, такого как директива с шаблоном):

<my-directive focus-on-load="input" />

вы можете использовать любой селектор jQuery вместо "ввода"

Ответ 26

Я хочу внести свой вклад в это обсуждение после поиска в лучшем решении и не находить его, создав его вместо этого.

Критерии: 1. Решение должно быть независимым от возможностей родительского контроллера, чтобы увеличить повторное использование. 2. Избегайте использования $watch для отслеживания некоторых условий, это медленное, увеличивает размер цикла дайджеста и упрощает тестирование. 3. Избегайте $timeout или $scope. $Apply() запускает цикл дайджеста. 4. Элемент ввода присутствует в элементе, где используется Директива.

Это решение, которое мне больше всего понравилось:

Директива:

.directive('focusInput', [ function () {
    return {
        scope: {},
        restrict: 'A',
        compile: function(elem, attr) {
            elem.bind('click', function() {
                elem.find('input').focus();                
            });
        }        
    };
}]);

Html:

 <div focus-input>
     <input/>
 </div>

Я надеюсь, что это поможет кому-то!

Ответ 27

Это легко.. попробуйте это

HTML

<select id="ddl00">  
 <option>"test 01"</option>  
</select>

Javascript

document.getElementById("ddl00").focus();

Ответ 28

Я думаю, что директива не нужна. Используйте атрибуты HTML и атрибуты класса, чтобы выбрать нужный элемент и использовать службу document.getElementById или document.querySelector для применения фокуса (или эквивалентов jQuery).

Разметка - это стандартные директивы HTML/ angular с добавлением id/classes для выбора

<input id="myInput" type="text" ng-model="myInputModel" />

Контроллер передает события

$scope.$emit('ui:focus', '#myInput');

В службе пользовательского интерфейса используется querySelector - если существует несколько совпадений (например, из-за класса), он возвращает только первый

$rootScope.$on('ui:focus', function($event, selector){
  var elem = document.querySelector(selector);
  if (elem) {
    elem.focus();
  }
});

Вы можете использовать $timeout(), чтобы заставить цикл дайджеста

Ответ 29

Просто бросьте кофе.

app.directive 'ngAltFocus', ->
    restrict: 'A'
    scope: ngAltFocus: '='
    link: (scope, el, attrs) ->
        scope.$watch 'ngAltFocus', (nv) -> el[0].focus() if nv

Ответ 30

Не уверен, что если полагаться на тайм-аут, это хорошая идея, но это работает для ng-repeat, потому что этот код запускается ПОСЛЕ angularjs обновляет DOM, поэтому вы убедитесь, что все объекты:

myApp.directive('onLastRepeat', [function () {
        return function (scope, element, attrs) {
            if (scope.$last) setTimeout(function () {
                scope.$emit('onRepeatLast', element, attrs);
            }, 1);
        };
    }]);
    //controller for grid
    myApp.controller('SimpleController', ['$scope', '$timeout', '$http', function ($scope, $timeout, $http)
    {
        var newItemRemoved = false;
        var requiredAlert = false;
        //this event fires up when angular updates the dom for the last item
        //it observed, so here, we stop the progress bar
        $scope.$on('onRepeatLast', function (scope, element, attrs) {
            //$scope.complete();
            console.log('done done!');
            $("#txtFirstName").focus();
        });
    }]);