0

我在使用ui-select和角度触摸的AngularJS应用程序中遇到问题。ui选择输入没有得到焦点点击:与角度触摸冲突

在Safari上,使用移动设备(如iPad或iPhone)时,当单击ui-select指令的文本输入字段时,虚拟键盘不会打开,输入不会获得焦点。

我发现它是角接触导致的问题,因为一旦我从应用程序中删除依赖项,一切正常工作再次。

HTML

<body ng-controller="DemoCtrl"> 
    <ui-select multiple 
      theme="select2" 
      ng-model="multipleDemo.selection" 
      reset-search-input="true" 
      style="min-width: 300px;"> 
    <ui-select-match placeholder="Enter an adress..."> 
     {{$item.formatted_address}} 
    </ui-select-match> 
    <ui-select-choices repeat="address in addresses track by $index" 
         refresh="refreshAddresses($select.search)" 
         refresh-delay="250"> 
     <div ng-bind-html="address.formatted_address | highlight: $select.search"></div> 
    </ui-select-choices> 
    </ui-select> 
    <p>Selected : {{multipleDemo.selection | selectionFilter}}</p> 

</body> 

JS

var app = angular.module('demo', ['ngSanitize', 'ui.select', 'ngTouch']); 

app.filter('selectionFilter', function() { 
    // Not important... see the plunker for detail. 
}); 

app.controller('DemoCtrl', function($scope, $http) { 
    $scope.multipleDemo = {}; 
    $scope.multipleDemo.selection = []; 

    $scope.address = {}; 
    $scope.refreshAddresses = function(address) { 
    var params = {address: address, sensor: false}; 
    return $http.get(
     'http://maps.googleapis.com/maps/api/geocode/json', 
     {params: params} 
    ).then(function(response) { 
     $scope.addresses = response.data.results; 
    }); 
    }; 

}); 

http://plnkr.co/edit/dFBQ4si6hLMP1S9dal7m?p=preview

是否有人有什么我可以做,以防止ngTouch从导致了问题的想法?我不能从依赖关系中删除ngTouch:我在其他地方需要它。

更新16/09

这个问题似乎来自角触的这一部分(1.4.8):

element.on('touchend', function(event) { 
    var diff = Date.now() - startTime; 

    // Use jQuery originalEvent 
    var originalEvent = event.originalEvent || event; 
    var touches = (originalEvent.changedTouches && originalEvent.changedTouches.length) ? 
     originalEvent.changedTouches : 
     ((originalEvent.touches && originalEvent.touches.length) ? originalEvent.touches : [originalEvent]); 
    var e = touches[0]; 
    var x = e.clientX; 
    var y = e.clientY; 
    var dist = Math.sqrt(Math.pow(x - touchStartX, 2) + Math.pow(y - touchStartY, 2)); 

    if (tapping && diff < TAP_DURATION && dist < MOVE_TOLERANCE) { 
    // Call preventGhostClick so the clickbuster will catch the corresponding click. 
    preventGhostClick(x, y); 

    // Blur the focused element (the button, probably) before firing the callback. 
    // This doesn't work perfectly on Android Chrome, but seems to work elsewhere. 
    // I couldn't get anything to work reliably on Android Chrome. 
    if (tapElement) { 
     tapElement.blur(); 
    } 

    if (!angular.isDefined(attr.disabled) || attr.disabled === false) { 
     element.triggerHandler('click', [event]); 
    } 
    } 

    resetState(); 
}); 

如果停用的条件下,加入&& false例如输入将重点放在点击上。 我需要找到一种方法来禁用这个事件绑定来自外部角度触摸库的输入。

回答

3

该指令的下方,施加在ui-select父指令,解决了这个问题:

app.directive('fixFocusOnTouch', function(){ 
    return { 
    restrict: 'A', 
    controller: function($element){ 
     /* 
     Usually, event handlers binding are made in the link function. 
     But we need this handler to be executed first, so we add it in the controller function instead. 
     */ 
     var inputElement = $element[0].querySelector('input.ui-select-search'); 
     angular.element(inputElement).bind('touchend', function(event){ 
     event.stopImmediatePropagation(); 
     }); 
    } 
    } 
}); 

它杀死touchend事件的当前传播通过角点触摸加入可以执行处理程序之前(见“更新”问题的一部分)。

我不能让它在普朗克上工作,但我会再试一次来提供一个工作示例。

用法:

<ui-select multiple fix-focus-on-touch 
      theme="select2" 
      ng-model="multipleDemo.selection" 
      reset-search-input="true" 
      style="min-width: 300px;"> 
    <ui-select-match placeholder="Enter an adress..."> 
    {{$item.formatted_address}} 
    </ui-select-match> 
    <ui-select-choices repeat="address in addresses track by $index" 
        refresh="refreshAddresses($select.search)" 
        refresh-delay="250"> 
    <div ng-bind-html="address.formatted_address | highlight: $select.search"></div> 
    </ui-select-choices> 
</ui-select>