web-dev-qa-db-ja.com

クリックイベントの要素にクラスを追加する

Angular Jsです。Js。クリックイベントの要素にクラスを追加する必要があります。次のコードを試してみましたが、機能しません。

<html>
<head>
    <style>
        .active{color:red;}
    </style>

    <script src="js/lib/jquery.min.js"></script>
    <script src="js/lib/angular.min.js"></script>
</head>
<body ng-app="MyApp" ng-controller="MyController">

    <div ng-repeat="data in datas">
        <p ng-click='selectMe()'>{{data.name}}</p>
    </div>

    <script>
    var app = angular.module('MyApp',[]);
    app.controller('MyController',function($scope){
         $scope.datas = [{name:"first"},{name:"second"}];

         $scope.selectMe = function (){
            $(this).addClass('active');
         }
    });

    </script>
</body>
</html>

このコードの問題は何ですか? ng-classを使用する必要はありますか?どうやってするの?

6
Sajith

$ eventを渡してクリックすることができます

<p ng-click='selectMe($event)'>{{data.name}}</p>

//code:
$scope.selectMe = function (event){
   $(event.target).addClass('active');
}
34
huston007

これを行うAngular方法(実際にはMVVM))は、クリックイベントを通じてモデルを更新してから、モデルに従ってペイントすることです。

app.controller('MyController',function($scope){
    $scope.datas = [{name:"first", selected:false},{name:"second",selected:false}];
    $scope.selectMe = function(data) {
        var i;
        for( i=0; i < $scope.datas.length; i++ ) {
            $scope.datas[i].selected = false;
        }
        data.selected = true;
    };
}

そしてHTML:

<div ng-repeat="data in datas">
    <p ng-click='selectMe(data)' ng-class="{selected: data.selected}>{{data.name}}</p>
</div>

この質問にはすでに回答があることを知っていますが、選択した最良の回答(コードの一部で既に実装済み)がAngularJSのドキュメントと一致していないことに気づいたときはショックを受けました。

AngularJS Documentation によると:

次の目的でコントローラを使用しないでください。

  • DOMの操作—コントローラーにはビジネスロジックのみを含める必要があります。プレゼンテーションロジックをコントローラーに配置すると、そのテスト容易性に大きく影響します。 Angularには、ほとんどの場合にデータバインディングがあり、手動のDOM操作をカプセル化するディレクティブがあります。

huston007の回答は適切に機能しますが、この推奨事項には従いません。

これをデータ入力として:

$scope.peeps = {
  '0': {
    'id': 0,
    'first_name': 'Tony',
    'last_name': 'Martin'
  },
  '1': {
    'id': 1,
    'first_name': 'Gerald',
    'last_name': 'Johanssen'
  },
  '2': {
    'id': 2,
    'first_name': 'Bobby',
    'last_name': 'Talksalot'
  }
};

そしてこれはあなたのhtmlです:

<ul>
  <li ng-repeat="peep in peeps" 
      ng-click="addOrRemoveClassFromMe(peep.id)"
      ng-class="{selected: selectedPeeps[peep.id]}">
     {{peep.first_name}} {{peep.last_name}}
  </li>
</ul>

私が提案するソリューションでは、人物のIDをキーとして、ブール値を値として持つオブジェクトの配列を使用します。これは、ngClassディレクティブを通じてDOMでリンクされます。

//-- create the selected peeps array
$scope.selectedPeeps = {};

//-- add the id to an array with a true-ey value
$scope.addOrRemoveClassFromMe = function(id) {

  //-- Set selected peeps as true/false
  if($scope.selectedPeeps[id]) {
    $scope.selectedPeeps[id] = false;
  } else {
    $scope.selectedPeeps[id] = true;
  }
};

私のcodepen here をチェックしてください。

コントローラーからこのロジックをすべて削除し、変数の定義のみを残す別のバージョンもありますが、これはこの質問の範囲外であると考えました。 (codepen.io/joshwhatk/pen/bwmid)

お役に立てれば。

6
joshwhatk

私はこれが古い質問であることを知っていますが、それに遭遇しただけであり、ここに与えられたもののいずれにもより簡単な答えがあると思います:

<div ng-repeat="data in datas">
    <p ng-click="active=!active"
       ng-class="{'active': active}">{{data.name}}</p>
</div>

datas配列を作成する以外に、コントローラーにコードは必要ありません。これは、コントローラーのスコープではなく、ng-repeatによって作成された各activeの子スコープ内にdiv変数が作成されるため、機能します。

@joshwhatkのcodepenの更新バージョンを作成しました here

4
duck