Focus New Tab的Textarea Bootstrap 3 + AngularJS

时间:2013-12-18 23:00:40

标签: javascript jquery html angularjs twitter-bootstrap

我有一些Bootstrap可切换选项卡,每个选项卡都包含一个textarea。我已将其设置为您可以创建包含textareas的新选项卡。但是,当创建这个新选项卡时,我希望它内部的textarea与光标一起聚焦。

以下是相关的问题代码,其中有一个稍微大一点的小提示,显示它的实际效果:http://jsfiddle.net/HB7LU/1390/ 对于小提琴,它应该在创建第一个项目后关注textarea。

function ListController($scope, topics) {

    var currentId = 0;
    $scope.mainList = topics;

    $scope.addItem = function() {
        topics.push({
            id: (currentId++),
            active: "active",
            name: $scope.newItem,
        });

        //clears input box
        $scope.newItem = "";

        //remove previous bootstrap active classes
        $('ul.nav-pills li.active').removeClass('active');
        $('.tab-content .tab-pane.active').removeClass('active');   

        //Can't get this part to work!!
        //(the textareas have dynamic id's)
        $('#textarea0').focus();
    }
}

令人沮丧的是,如果我创建一个按钮并将其直接聚焦在控制器之外,我可以聚焦textarea。 (小提琴中有一个例子)。这让我相信我正在尝试将textarea集中在实际创建之前,但我尝试了一个回调函数,但这也没有用 - 也许我搞砸了。

1 个答案:

答案 0 :(得分:1)

Angular建议您不要在控制器内部进行DOM操作。这条线在这里是模糊的,因为你在技术上在指令中进行操作,但是使用控制器函数来完成它。我个人会避免这种情况。

在任何一种情况下,在指令中执行此操作的一个好处是可以让您轻松访问element。这样可以很容易地使用jQlite,它是Angular aware vs jQuery。

所以我会在您的控制器中删除导致您遇到麻烦的这一行:$('#textarea0').focus();

而是,将此jQlite行添加到您的指令:

angular.element(document.querySelector('#textarea0')).focus();

所以你的指令现在看起来像这样:

myApp.directive('ngEnter', function ($timeout) {
    return function (scope, element, attrs) {
        element.bind("keydown keypress", function (event) {
            if(event.which === 13) {
                scope.$apply(function (){
                    scope.$eval(attrs.ngEnter);
                });
                angular.element(document.querySelector('#textarea0')).focus();

                event.preventDefault();
            }
        });
    };
});

这可以解决您的问题:updated fiddle

但是我也会将两条removeClass行移到你的指令中,并使用jQlite代替那里 - 如果是我的话。然后,当指令处理DOM时,您的控制器功能可以专注于与列表相关的任务。