2017-10-06 15 views
7

私の次のアプリケーションでは、myelement(角度方向のラッパーがinputタグ)の複数の行があります。一度にフォーカス/選択/ハイライトのいずれかを強調する必要がありますが、スタイルでは.selectedクラスがそうです。要素フォーカスの要素の角度バインドクラス

次のアプリケーションでは、selectedというコードでバインドする必要があるinputタグのフォーカスを除いてすべて正常に動作します。 I. selectedクラスを持つどの要素でも、対応するinputタグにフォーカスを当てる必要があります。どのように私はそれをacieveできますか?

<!doctype html> 
<html> 
<head> 
    <meta charset="utf-8"> 
    <title></title> 
    <meta name="description" content=""> 
    <meta name="viewport" content="width=device-width"> 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script> 
    <style> 
    .container { 
     display: flex; 
     flex-direction: column; 
     width: 600px; 
    } 
    .notebook { 
     display: flex; 
     justify-content: center; 
    } 
    .cell { 
     margin: 5px; 
     padding: 5px; 
    } 
    .selected { 
     border-style: solid; 
     border-color: green; 
     border-width: 1px; 
     border-left-width: 5px; 
    } 
    </style> 
</head> 

<body ng-app="myApp"> 

<div ng-controller="ListController as listctrl" class="notebook"> 

    <div class="container"> 
    <myelement ng-repeat="i in listctrl.list" 
     ng-click="listctrl.selected = $index" 
     ng-class="{selected : listctrl.selected === $index}" 
     class="cell"></myelement> 
    </div> 
</div> 

<script type="text/javascript"> 
angular 
    .module('myApp',[]) 
    .controller('ListController', function($scope) { 
    var listctrl = this; 
    listctrl.list = []; 
    listctrl.selected = 0; 

    listctrl.addCell = function() { 
     var x = listctrl.list.length; 
     listctrl.list.push(x); 
     listctrl.selected = listctrl.list.length - 1; 
    } 

    listctrl.addCell(); 

    $scope.$on('add', function (event, message) { 
     $scope.$apply(listctrl.addCell); 
    }); 

    $scope.$on('keyUp', function(event) { 
     $scope.$apply(function(){ 
     listctrl.selected = listctrl.selected - 1; 
     }); 
    }); 

    $scope.$on('keyDown', function(event) { 
     $scope.$apply(function(){ 
     listctrl.selected = listctrl.selected + 1; 
     }); 
    }); 
    }) 
    .directive('myelement', function($rootScope){ 

    return { 
     template: '<input style="width: 95%"></input>', 
     restrict: 'E', 
     link: function (scope, element, attrs) { 

     var inputTag = element[0].children[0]; 
     inputTag.focus(); 

     element.on('keydown', function(event) { 
      if (event.keyCode === 13 && event.shiftKey) { 
      $rootScope.$broadcast('add'); 
      } else if (event.keyCode === 38) { 
      $rootScope.$broadcast('keyUp'); 
      } else if (event.keyCode === 40) { 
      $rootScope.$broadcast('keyDown'); 
      } 
     }); 
     }, 
     controller: function ($scope) { 

     } 
    }; 
    }) 
</script> 

</body> 
</html> 
+0

ng-class = "{selected:listctrl.selected === $ index}"には "?" selectedとlistctrl.selectedの間には三項関係があるのでまたは私はそれを間違って読んでいます。 –

+1

@Dream_Capそれは3進ではなく、オブジェクトリテラルだけです – Phil

+0

'element.hasClass( 'selected')&& inputTag.focus()'のようなものを使用できませんか?あなたのディレクティブの 'priority'を' 0'よりも大きい値に設定する必要があるかもしれません。そのため、 'ngClass'の後にpost-link関数が実行されます。 – Phil

答えて

4

以下の例を検討してください。現在推奨されているAngularJSのcomponent機能を使用しています(v1.5以降)。この例は非常にシンプルなので、何が起こっているのか、プロジェクトでどのように適用するのかを簡単に理解できます。

はJavaScript

class MainController { 

    constructor() { 
     this.focused = true; 
    } 

} 

class MyElementController { 

    constructor($element) { 
     this.$element = $element; 
    } 

    $onChanges(changes) { 
     if (changes.focused.currentValue === true) { 
      this.$element[0].getElementsByTagName('input')[0].focus(); 
     } 
    } 

} 

const myElementComponent = { 
    bindings: { 
     focused: '<' 
    }, 
    controller: MyElementController, 
    template: `<input type="text">` 
}; 

angular 
    .module('app', []) 
    .controller('MainController', MainController) 
    .component('myElement', myElementComponent); 

HTML

<body ng-app="app" ng-controller="MainController as vm"> 
    <my-element focused="vm.focused"></my-element> 
</body> 
4

var elementComponent = { 
 
bindings:{ 
 
    selected:'<' 
 
    }, 
 
    controller:function($element){ 
 
    this.$onChanges = function(changes) { 
 
     if(changes.selected.currentValue){ 
 
     $element[0].getElementsByClassName('textName')[0].focus() 
 
     } 
 
    } 
 
    }, 
 
    template:'<input type="text" class="textName" style="margin:4px">' 
 
}; 
 

 
var controller = function(){ 
 
    this.list = [1]; 
 
    this.selected = 1 
 
    this.add = function(){ 
 
    var length = this.list.length ; 
 
     this.list.push(length + 1); 
 
     this.selected = length + 1; 
 
    } 
 
}; 
 

 

 
angular.module('app', []) 
 
     .component('element', elementComponent) 
 
     .controller('appCtrl', controller);
<!DOCTYPE html> 
 
<html> 
 
<head> 
 
    <meta charset="utf-8"> 
 
    <meta name="viewport" content="width=device-width"> 
 
</head> 
 
<body ng-app="app" ng-controller="appCtrl as vm" > 
 
<script src="https://rawgit.com/angular/bower-angular/master/angular.min.js"></script> 
 
    <button ng-click="vm.add()">Add New Cell</button> 
 
    <div ng-repeat="item in vm.list" > 
 
    <element selected="item == vm.selected" ng-click="vm.selected = item"></element> 
 
    </div> 
 
    Selected Element : {{vm.selected}} 
 
</body> 
 
</html>

これはあなたの条件を満たしかもしれません。

1

すべてのキーアップ/完了時にクラスをチェックし、focus()、blur()を使用して入力状態を変更します。タブプレスの場合には、でpreventDefault()

angular 
 
    .module('myApp',[]) 
 
    .controller('ListController', function($scope) { 
 
    var listctrl = this; 
 
    listctrl.list = ['1','2','3']; 
 
    listctrl.selected = 0; 
 

 
    listctrl.addCell = function() { 
 
     var x = listctrl.list.length; 
 
     listctrl.list.push(x); 
 
     listctrl.selected = listctrl.list.length - 1; 
 
    } 
 

 
    listctrl.addCell(); 
 

 
    $scope.$on('add', function (event, message) { 
 
     $scope.$apply(listctrl.addCell); 
 
    }); 
 

 
    $scope.$on('keyUp', function(event) { 
 
     $scope.$apply(function(){ 
 
     listctrl.selected = listctrl.selected - 1; 
 
     }); 
 
    }); 
 

 
    $scope.$on('keyDown', function(event) { 
 
     $scope.$apply(function(){ 
 
     listctrl.selected = listctrl.selected + 1; 
 
     }); 
 
    }); 
 
    }) 
 
    .directive('myelement', function($rootScope){ 
 
    return { 
 
     template: '<input style="width: 95%"></input>', 
 
     restrict: 'E', 
 
     scope: {}, 
 
     link: function (scope, element, attrs) { 
 
     var inputTag = element[0].children[0]; 
 
     var updateFocues = function(element) { 
 
      if(element[0].className.indexOf('selected') !== -1) { 
 
      scope.$apply(function() { 
 
       inputTag.focus() 
 
      }); 
 
      } else { 
 
      scope.$apply(function() { 
 
       inputTag.blur() 
 
      }); 
 
      }  
 
     } 
 

 
     element.on('keydown', function(event) { 
 
      if (event.keyCode === 13 && event.shiftKey) { 
 
      $rootScope.$broadcast('add'); 
 
      } else if (event.keyCode === 38) { 
 
      $rootScope.$broadcast('keyUp'); 
 
      } else if (event.keyCode === 40) { 
 
      $rootScope.$broadcast('keyDown'); 
 
      }else if (event.keyCode === 9) { 
 
      event.preventDefault(); 
 
      } 
 
     }); 
 
     
 

 
     scope.$on('keyUp', function() { 
 
      updateFocues(element) 
 
     }) 
 
     scope.$on('keyDown', function() { 
 
      updateFocues(element) 
 
     }) 
 
     }, 
 
     controller: function ($scope) { 
 

 
     } 
 
    }; 
 
    })
.container { 
 
     display: flex; 
 
     flex-direction: column; 
 
     width: 600px; 
 
    } 
 
    .notebook { 
 
     display: flex; 
 
     justify-content: center; 
 
    } 
 
    .cell { 
 
     margin: 5px; 
 
     padding: 5px; 
 
    } 
 
    .selected { 
 
     border-style: solid; 
 
     border-color: green; 
 
     border-width: 1px; 
 
     border-left-width: 5px; 
 
    }
<!doctype html> 
 
<html> 
 
<head> 
 
    <meta charset="utf-8"> 
 
    <title></title> 
 
    <meta name="description" content=""> 
 
    <meta name="viewport" content="width=device-width"> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script> 
 

 
</head> 
 

 
<body ng-app="myApp"> 
 

 
<div ng-controller="ListController as listctrl" class="notebook"> 
 

 
    <div class="container"> 
 
    <myelement ng-repeat="i in listctrl.list" 
 
     ng-click="listctrl.selected = $index" 
 
     ng-class="{selected : listctrl.selected === $index}" 
 
     class="cell"></myelement> 
 
    </div> 
 
</div> 
 
</body> 
 
</html>

0

あなたは(ほとんどの場合、それはあなたのニーズにフィットする)代わりにCSSを使用して提案します。シンプルなビヘイビアをサポートするために余分なJSコードを追加するのは良い方法ではありません。

:focusセレクタexplained on W3C

例えば

myelement input:focus { 
    border-style: solid; 
    border-color: green; 
    border-width: 1px; 
    border-left-width: 5px; 
} 
関連する問題