19

ブートストラップ「ボタングループ」と統合するための小さな角度モジュールを作成しました(ラジオボタンのように機能させるためのJavaScriptを少し追加しました。チェックボックスに対して同じことを行うために、このモジュールで作成しました:http://jsfiddle .net/evaneus/z9rge/

私のコードはhttp://jsfiddle.net/askbjoernhansen/YjMMD/にあります

私の質問:

1)これは正しいアプローチですか?

2) モデルは 3 回監視されますか、それとも $scope.$watch() は同じモデルであると判断して 1 回だけ監視しますか? そのようです。

3) 私のように $watch 関数で DOM をいじるのは「正しい」でしょうか? 「汚い」と感じますが、それは、angularjs とネイティブに互換性がないものに angular を追加するときに求めていることだと思います。または?

4) 各ボタンの代わりに btn-group に ng-model 属性を配置する方法はありますか? それはそれをもっときれいに見せるでしょう。

上記のjsfiddleで確認できます。または、コードはここにあります。最初はhtmlです。

 <!-- to test the two-way model -->
  <input name="test" type="radio" ng-model="myModel['A']" value="left"> Left<br>
  <input name="test" type="radio" ng-model="myModel['A']" value="middle"> Middle<br>
  <input name="test" type="radio" ng-model="myModel['A']" value="right"> Right<br>


myModel A {{myModel['A']}}<br/>

<div class="btn-group" data-toggle="buttons-radio">
  <button type="button" buttons-radio=""
    ng-model="myModel['A']" value="left"   class="btn">Left</button>
  <button type="button" buttons-radio=""
    ng-model="myModel['A']" value="middle" class="btn">Middle</button>
  <button type="button" buttons-radio=""
    ng-model="myModel['A']" value="right"  class="btn">Right</button>
</div>

そしてJavaScript:

angular.module('buttonsRadio', []).directive('buttonsRadio', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function($scope, element, attr, ctrl) {
            element.bind('click', function() {
                $scope.$apply(function(scope) {
                    ctrl.$setViewValue(attr.value);
                });
            });

            // This should just be added once, but is added for each radio input now?
            $scope.$watch(attr.ngModel, function(newValue, oldValue) {
                element.parent(".btn-group").find('button').removeClass("active");
                element.parent(".btn-group")
                .find("button[value='" + newValue + "']").addClass('active');
            });
        }
    };
});​
4

2 に答える 2

26

ボタンごとに 1 回、合計 3 回ディレクティブを呼び出しています。私の知る限り、これは、リンク関数が 3 回呼び出され、イベントがバインドされ、変更が監視されることを意味します。これについて以下にもう少し追加します。

モデルが変更されたときに DOM を変更することは問題ありませんが、行っていること (クラスと値の変更) は、双方向データ バインディングと次のようなネイティブ ディレクティブを使用して angular によって自動的に実行できます。ng-class

オプションのリストを指定してボタンをレンダリングするディレクティブを作成できます。たとえば、このモデルとこれらのオプションがある場合

$scope.myOptions = ["Left", "Middle", "Right"];
$scope.myModel = "Left"

buttons-radioこのようなディレクティブ を作成できます

App.directive('buttonsRadio', function() {
    return {
        restrict: 'E',
        scope: { model: '=', options:'='},
        controller: function($scope){
            $scope.activate = function(option){
                $scope.model = option;
            };      
        },
        template: "<button type='button' class='btn' "+
                    "ng-class='{active: option == model}'"+
                    "ng-repeat='option in options' "+
                    "ng-click='activate(option)'>{{option}} "+
                  "</button>"
    };
});​

HTMLから呼び出すことができます

<buttons-radio class="btn-group" data-toggle="buttons-radio" 
               model='myModel'    
               options='myOptions'>
</buttons-radio>

注意事項:

  1. テンプレートは、ng-repeatすべてのオプションを通過し、それに応じてボタンをコンパイルするディレクティブを使用します。
  2. ディレクティブには、独自のコントローラーと分離されたスコープがmodelありoptions、双方向バインディングを受け入れるため、ディレクティブが値を変更すると、angular がその魔法を実行します。
  3. オプションがモデルの現在の値と一致する場合、ボタンにactiveクラスが割り当てられます。
  4. ボタンが押されると、activate(ディレクティブ コントローラーからの) メソッドが呼び出され、モデルの値が変更されます。

こちらはJSFiddle http://jsfiddle.net/jaimem/A5rvg/4/


編集

これについては完全にはわかりませんでしたが、モデルには3 つの異なるウォッチャーがあり、ディレクティブの呼び出しごとに 1 つずつあります。Batarangを使用している場合は、[パフォーマンス] タブとAngularJS の [プロパティ] パネルから、監視されているすべての式を確認できます。Batarang は$scope便利なプロパティも公開しているため、コンソールから次のコマンドを実行して、モデルのウォッチ オブジェクトを探すことができます。

$scope.$$watchers.filter(function(w){return w.exp ==="myModel['A']"}); 
于 2012-11-19T08:56:31.613 に答える
7

これは簡単です

<html>
    <div class="btn-group" data-toggle="buttons">
      <span class="btn btn-primary" ng-click="worktype=1" ng-class="worktype==1?'active':''">
        <input type="radio"   value="1">全职
      </span>
      <span class="btn btn-primary" ng-click="worktype=2" ng-class="worktype==2?'active':''">
        <input type="radio"   value="2">兼职
      </span>
    </div>
</html>
于 2014-08-14T13:57:05.003 に答える