【问题标题】:Focus New Tab's Textarea Bootstrap 3 + AngularJSFocus New Tab 的 Textarea Bootstrap 3 + AngularJS
【发布时间】:2013-12-18 23:00:40
【问题描述】:

我有一些 Bootstrap 可切换选项卡,每个选项卡都包含一个文本区域。我已经设置好了,所以你可以创建一个包含 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 实际创建之前对其进行聚焦,但是我尝试执行回调函数,但这也不起作用-也许我搞砸了。

【问题讨论】:

    标签: javascript jquery html angularjs twitter-bootstrap


    【解决方案1】:

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

    在任何一种情况下,在指令中执行此操作的一个优点是它可以让您轻松访问element。这使得使用 Angular 与 jQuery 的 jQlite 变得容易。

    所以我会删除你的控制器中给你带来麻烦的这一行:$('#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。

    【讨论】:

    • 感谢您对更好的 Angular 实践的见解。我刚开始使用 Angular,所以这是一个非常有用的答案。此解决方案的唯一问题是,由于我在创建时动态标识 textarea,因此我必须使用 $('#textarea' + currentId) 选择它们,但 currentId 的范围在控制器内。我显然可以将它移到控制器之外并给它更大的范围,但这对我来说感觉不对,可能不是最佳实践。有没有更好、更 Angular 的方法来解决这个问题?
    • 如果我关注你,你可以让addItem 返回currentId - 所以它可以在你的指令中用于querySelector()
    • 这是一个例子:jsfiddle.net/HB7LU/1397(我没有使用 currentId- 但你会看到返回值是如何通过的)
    猜你喜欢
    • 1970-01-01
    • 2019-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多