0

prettyCheckbox プラグインを使用して、チェックボックスにスタイルを適用しようとしています。プラグインが元のチェックボックスを隠し、代わりに別のスタイルのオブジェクトを表示する方法を知らない人のために。チェックボックスごとにプラグインをインスタンス化するディレクティブを作成しました。

偽のチェックボックスをクリックすると、プラグインは実際の入力要素のプロパティを設定し、変更を呼び出します-ただし、これはモデルを更新していないようです:

input.prop('checked', true).change();

モデルを更新するために、クリック イベントを使用して元のチェックボックスが変更されるように、prettyCheckbox プラグインを少し修正しました。

input.trigger('click');

これは正常に機能しますが、チェックボックスは常に、期待する値とは正反対の値を持っているようです: チェックボックスがチェックされていない場合は true 、チェックボックスがチェックされている場合は false です。なぜこれが起こっているのか分かりません。何が起こっているかを示すために plunkr を作成しました。

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

助けてくれてありがとう:)

4

2 に答える 2

1

そうです、私はこのjsfiddleを見つけました。これは、きれいなチェックボックスプラグインを使用せずに物事を理解するのに本当に役立ちました:

http://jsfiddle.net/evaneus/z9rge/

James が彼の回答で述べたように、ディレクティブにはコントローラーへのアクセスが必要です。

angular.module('buttonToggle', []).directive('buttonToggle', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function($scope, element, attr, ctrl) {
            var classToToggle = attr.buttonToggle;
            element.bind('click', function() {
                var checked = ctrl.$viewValue;
                $scope.$apply(function(scope) {
                    ctrl.$setViewValue(!checked);
                });
            });

            $scope.$watch(attr.ngModel, function(newValue, oldValue) {
                newValue ? element.addClass(classToToggle) : element.removeClass(classToToggle);
            });
        }
    };
});


<p>
  <input id="gradeCheck" type="checkbox" ng-model="myModel['A']"> A
  <input type="checkbox" ng-model="myModel['B']"> B
  <input type="checkbox" ng-model="myModel['C']"> C
  <input type="checkbox" ng-model="myModel['D']"> D
</p> 

<p>
  <button button-toggle="active" class="btn" ng-model="myModel['A']">A</button>
  <button button-toggle="active" class="btn" ng-model="myModel['B']">B</button>
  <button button-toggle="active" class="btn" ng-model="myModel['C']">C</button>
  <button button-toggle="active" class="btn" ng-model="myModel['D']">D</button>
</p>

次に、アクティブなスタイルの有無にかかわらず、ボタンを希望どおりにスタイルするだけで、すべてうまく機能しました:)

于 2013-08-05T11:36:00.443 に答える
1

input.trigger('click')別のイベント ハンドラの途中で呼び出されます。JavaScript はシングル スレッドであるため、イベント ループは一度に 1 つのイベントしか処理できず、イベントは既に処理されているため、このイベントはイベント キューが解放されるとすぐに処理されます。あなたの場合、「クリック」イベントを処理できるようになるまでに、角度がダイジェストサイクルの実行を終了した後です。これは、チェックボックスが実際にクリックされる前に angular がすでに処理を完了していることを意味し、チェックボックスのクリックが完了すると、「showRedBox」値がクリーン (ダーティではない) と見なされるため、angular はそれを無視します。アンギュラーが「showRedBox」をもう一度見て、現在の値を古い値と比較し、それが汚れていることを認識し、DOM を更新するのは、きれいなチェック ボックスをもう一度クリックするまでではありません。もちろん、それが完了するまでに、チェックボックスの状態が再び変更されていないため、同期されていません。通話中$scope.$apply()$scope.$digest()angularはすでに「showRedBox」がクリーンであると考えているため、この状況では役に立ちません。最初にangularのデータを変更して、「showRedBox」値がダーティとして認識されるようにする必要があります。これは、スコープにアクセスできる場合にのみ実行できます(アクセスできません)。

解決策:「showRedBox」値を直接変更するscope.showRedBox = fakeCheckable.hasClass("checked");代わりに使用します。input.trigger('click')この解決策では、プラグインのスコープをディレクティブのクロージャー内に収まるように修正する必要があります。

于 2013-08-02T16:50:04.163 に答える