Angular ui-bootstrap-tpls-0.12.1打开模态对话框设置焦点

时间:2015-05-02 07:45:10

标签: javascript angularjs twitter-bootstrap focus

我目前正在玩角度,尤其是带有自举模块的角度(现在谁可以没有自举?)。

在任何情况下,是否有人有一个干净的解决方案,用于将焦点放在弹出打开的新模式对话框中的输入字段上? 这个基本功能似乎不支持开箱即用。 我以为我可以在"打开"未来 - 但它似乎很早就被召唤。

所以,当你打开一个模态实例时 - 例如

$modal.open({
                "templateUrl": 'myModalContent.html',
                "controller" : 'modalInstanceCtrl',
                "size": size,
                "resolve" : {
                    "items": function () {
                        return $scope.items;
                    }
                }
            });

然后,您可以将模态实例用于广播偶数:

 modalInstance.opened.then(function(){
                $rootScope.$broadcast(myNewDirectiveBootstrapConfig.events.modalInstanceOpened
                        , modalInstance);
            });

现在我想要关注的输入元素将使用指令进行角度增强。

<label for="popupTitle">Title:</label>
<input type="text" class="form-control" id="popupTitle"
       ng-required="true"
       ng-model="popup.title"
       ng-minlength="1"
       newdirective-modal-focus
       >

指令代码不会侵入并且与页面逻辑无关。理想情况下,您只需要使用事件API,并且调用非侵入式指令并执行焦点魔术。

angular.module('newDirectivesModule', [])
.constant('myNewDirectiveBootstrapConfig', {
    events: {
        modalInstanceOpened : "modalInstanceOpened"
    }
})
.directive('newdirectiveModalFocus', ['myNewDirectiveBootstrapConfig',    
function (myNewDirectiveBootstrapConfig) {
    return {
      restrict:'A', // process compile directive only on element attributes


       link: function(scope, elm, attr) {             
             scope.$watch(function(){return elm.is(":visible");}, function(value) {
                 if(elm.is(":visible")){
                     elm.focus();                         
                 }                   
             });

             scope.$on(myNewDirectiveBootstrapConfig.events.modalInstanceOpened, function(event, data) {
                 if(elm.is(":visible")){
                     elm.focus();
                 }                   
             });                                  
        }          
    };
}]);

您在代码中看到我使用不同的观看场景。 实际情况是,指令代码被调用给儿子。 open.then未来似乎是发布事件,说明模型在您实际看到浮动在屏幕上的模态对话框之前是打开的。 输入元素被告知要设置焦点 - 但显然很快,如果我调试它仍然在后台调用focus()时。 IT是可见的,在某种意义上说,你可以在页面的dom中进行查找,并且在某种意义上,如果你问JQuery(&#34;:visible&#34;)dom元素,它确实是可见的。但它仍然是看不见的。

我在其他地方看到的方法与我的完全不同,不依赖于事件,而是依赖于属性值从true变为false。 我根本不喜欢这个apporach因为它与页面的业务逻辑太耦合了,我不喜欢并拒绝作为解决方案。

对此的解决方案应该完全依赖于这样一个事实:模态对话框在其主体中只有一个单独的输入元素,其焦点在于我的指令,并且尽可能与页面逻辑分离。

理想情况下,这应该是bootsrap angular本身支持的功能,遗憾的是它似乎不是,但由于我们必须 - 无论如何 - 使用API​​来oepn对话框并关闭它们,我们应该能够扩展这一步以十字切割的方式获得焦点特征。

对此有何建议?

1 个答案:

答案 0 :(得分:3)

我对焦点post link使用不同的指令方式来确保元素被渲染(无论模态与否):

app.directive('focusMe',
    ['$timeout',
        function ($timeout) {
            return {
                link: {
                    pre: function preLink(scope, element, attr) {
                      // ...
                    },
                    post: function postLink(scope, element, attr) {
                        $timeout(function () {
                            element[0].focus();
                        }, 0);


                    }
                }
            }
        }]);

所以输入应该如下:

<input type="text" 
       focus-me
       class="form-control" id="popupTitle"
       ng-required="true"
       ng-model="popup.title"
       ng-minlength="1">

Plunker

中的演示