简体   繁体   English

状态改变后保持焦点

[英]Keep element in focus after state changed

In my AngularJS/Ui-Router application I have a series of input box like this: 在我的AngularJS / Ui-Router应用程序中,我有一系列输入框,如下所示:

<input ng-model="vm.filter" ng-keyup="vm.onKeyUp($event)" type="text" class="form-control" id="filter">

Then I have a controller, in which I have put the onKeyUp function, that looks like this: 然后,我有一个控制器,其中放置了onKeyUp函数,如下所示:

var vm = this;
vm.onKeyUp = function (e) {
    var val = e.currentTarget.value;
    $state.go('aState', { 'filter': val });
}

This will fire the state change (really just state parameter filter is changed) that will call a resolve behind the scene and at the end of the flow, my data set is filtered and the subset is showed. 这将触发状态更改(实际上只是更改状态参数filter ),这将在后台调用解析 ,并且在流程结束时,将过滤我的数据集并显示子集。 Amazing. 惊人。

But there is a little problem: on the state changed the HTML input lost its focus, and I can't figure out how can set it on focus at the end of the flow. 但是有一个小问题:在状态更改后,HTML输入失去了焦点,我不知道如何在流程结束时将其设置为焦点。 This is necessary since the user start to write in the input box and then will be surprised when his focus get "misteriously" lost. 这是必要的,因为用户开始在输入框中进行书写,然后当他的焦点“奇迹般地”丢失时会感到惊讶。 Bad UI experience. 不良的UI体验。

Ok for what can i read you just call the same state with different parameters on the url ( :filter ), what happens even if the state is the same is that the stateChange force a reload of the view and therefore the lost of the focused element. 好了,我能读到什么,只是在url( :filter )上使用不同的参数调用相同的状态,即使状态相同,也会发生的情况是stateChange强制重新加载视图,因此丢失了焦点元素。

And that is the behaviour unless you make a event.preventDefault() on $stateChangeStart but im pretty sure your data will not be updated. 除非您在$stateChangeStart上创建一个event.preventDefault() ,但是我非常确定您的数据不会被更新,否则这就是行为。

So possible solutions are imho: 因此可能的解决方案是恕我直言:

  1. Rethink your flow so it doenst depend on state change. 重新考虑您的流程,使其确实取决于状态变化。 (No need to code here :P) (无需在这里编码:P)

  2. Find a way to save your active element and set it on reload, like. 找到一种保存活动元素并将其设置为重新加载的方法,例如。

     //sessionStorage to prevent data stored after window is closed; $scope.$on('$stateChangeStart', function(){ $window.sessionStorage.setItem('focusedId', '#' + document.activeElement.id); }); $scope.$on('$viewContentLoaded', function(){ if((var id = $window.sessionStorage.getItem('focusedId'))) { $DOM.focus(id); //Use a service for DOM manipulation, you know manipulation in controllers is bad :( } }); 

` the service could be like this: `服务可能是这样的:

.factory('$DOM', ['$window', '$timeout', function ($window, $timeout) {
    return {
        __constructor: function (selector, event) {
             $timeout(function () {
                 var element = (typeof selector == 'object') ? 
                               selector :    
                               $window.document.querySelector(selector);

                 (!!element && !!element[event]) ? element[event]() : null;
              });
          },
          focus: function (selector) {
              this.__constructor(selector, 'focus');
          },
          blur: function (selector) {
              this.__constructor(selector, 'blur');
          }, //and so....
      };
}])

comment if you find a better way, maybe you can refresh the data preventing the refresh of the view and my understanding of ui.router is wrong :) 如果您找到更好的方法,请发表评论,也许您可​​以刷新数据以防止刷新视图,而我对ui.router的理解是错误的:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM