Angular指令重获焦点

Angular directive regain focus

本文关键字:焦点 指令 Angular      更新时间:2023-09-26

我有一个简单的TODO应用程序(来自Apress的书,Pro Angular)。目前,我有一个小的应用程序,其中用户输入一些信息到一个框,单击一个按钮和一个TODO任务弹出到屏幕上。我想要发生的是,在用户单击按钮将任务添加到页面后,然后焦点再次转到输入文本框。我目前的工作,但我想有这作为一个指令,所以我可以重用它。

JS

 var model = {
            user: "Adam"
        }
        var todoApp = angular.module('todoApp',[]);
        //get data
        todoApp.run(function($http){
            $http.get('todo.json').success(function(data){
                model.items = data;
            });
        });
        //need a directive that can listen for a button click
        todoApp.directive('refocus',function(){
            return {
                restrict: 'a',
                link: function(scope, elem, attrs){
                    scope.$watch('someEvent',function(){
                        //how to listen for a specific click event
                        //and return focus to the input element afterwards
                    })
                }
            }
        })
        todoApp.filter('checkedItems',function(){
            return function(items,showComplete){
                var resultArr=[];
                angular.forEach(items,function(item){
                    if(item.done==false || showComplete ==true){
                        resultArr.push(item);
                    }
                })
                return resultArr;
            }
        })
        todoApp.controller('ToDoCtrl',function($scope){
            $scope.todo = model;
            $scope.incompleteCount = function(){
                var count =0;
                angular.forEach($scope.todo.items,function(item){
                    if(!item.done){
                        count++;
                    }
                });
                return count;
            }
            $scope.addNewItem = function(actionText){
                $scope.todo.items.push({action: actionText, done: false});
                $scope.actionText = "";
                $scope.returnFocus('#getFocus');
            };
            $scope.returnFocus = function(elem){
                $(elem).focus();
            };
        });
HTML

<body ng-controller="ToDoCtrl">
<div class="page-header">
    <h1>
        {{todo.user}}'s To Do List
<span class="label label-default">
</span>
    </h1>
</div>
<div class="panel">
    <div class="input-group">
        <input id="getFocus" ng-model="actionText" class="form-control" ng-focus="" />
<span class="input-group-btn">
<button ng-click="addNewItem(actionText)" class="btn btn-default">Add</button>
</span>
    </div>
    <table class="table table-striped">
        <thead>
        <tr>
            <th>Description</th>
            <th>Done</th>
        </tr>
        </thead>
        <tbody>
            <tr ng-repeat="item in todo.items | checkedItems: showComplete | orderBy:'done'">
                <td>{{item.action}}</td>
                <td><input type="checkbox" ng-model="item.done"/></td>
            </tr>
        </tbody>
    </table>
    <div class="checkbox-inline">
        <label><input type="checkbox" ng-model="showComplete">Show complete</label>
    </div>
</div>
</body>

您可以在addNewItem函数中看到,我使用jQuery选择器将焦点返回到输入文本,但这并不能使其可重用。我怎样才能完成我的存根指令,使这种类型的行为可重用?

有几个模块可以做到这一点。(无耻塞!)这里有一个:角聚焦-on

我的方法是通过使用事件。这是非常直接和简单的。下面是一个实现模块的示例。

快速查看我更改的行:

首先将模块添加到你的应用程序中:

var todoApp = angular.module('todoApp',['kf.focusOn']);

然后我们通过添加focus-onevent="todoAdded"属性来使用它。因此,当todoAdded事件被触发时,该元素将被聚焦。

<input ng-model="actionText" class="form-control" focus-on event="todoAdded" />

现在在控制器中,我们所要做的就是$scope.$broadcast('todoAdded'),以便触发todoAdded事件。它看起来像:

$scope.addNewItem = function(actionText){
    $scope.$broadcast('todoAdded'); // this fires an event.
    $scope.todo.items.push({action: actionText, done: false});
    $scope.actionText = "";
};

现在让我们来看看模块是如何工作的:

angular.module('kf.focusOn', [])
.directive('focusOn', [function() {
    return {
        restrict: 'A', // Restrict to attribute only
        scope: {
            event: '@' // Accept an event attribute.
        },
        link: function($scope, elem) {
            $scope.$on($scope.event, function() { // On the event passed by $scope.event...
                elem[0].focus(); // Focus on the element.
            });
        }
    }
}]);

正如你所看到的,它没有什么特别的,而且非常简单,它接受一个event范围,并在事件被触发时将焦点应用到元素上。