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>