8

そこで、Angular を使用してカスタム確認ボックスを実装しようとしています。理想的には、機能を有効にする属性を追加したいだけです。例:

<button type="button" ng-click="delete(foo)">Delete</button>  ->  <button type="button" ng-click="delete(foo)" ng-confirm="Are you sure you want to delete this foo?">Delete</button>

(foo は ng-repeat 内にあります... fooList 内の foo..)

したがって、私が抱えているすべての問題は、通常は別のボタンに発生するクリック イベントを関連付けることに関連しています。モーダルを作成し(ブートストラップを使用しない)、すべての表示/非表示/などを処理する別のディレクティブ「confirmBox」があります。

私が現在使用しているものでは、本当に避けたい ng-click 機能を変更する必要があります。

現在の実装:

<button ... ng-click="confirm('Are you sure you want to delete this foo?, 'delete', foo)">Delete</button>

var confirmModule = angular.module('confirm', []);

confirmModule.run(function($rootScope) {
    $rootScope.confirm = function(text, func, obj) {
        $rootScope.$broadcast('confirm', func, obj, text);
    };
});

confirmModule.directive('confirmBox', function($parse) {

    return {
        restrict: 'A',
        template: myModalTemplate,
        link: function(scope, element, attrs){
            element.hide();
            var noBtn = element.find("[name='no']");
            noBtn.bind("click", function() {
                element.hide();
            });
            scope.$on("confirm", function(event, func, obj, text) {
                var yesBtn = element.find("[name='yes']");
                element.show();
                yesBtn.unbind("click").bind("click", function() {
                    scope[func](obj);
                });
            });
        }
    }
});

誰にもアイデアはありますか?ボタンのディレクティブを追加することから始めて、クリックイベントのバインドを解除して、ng-click発生しないようにしました。次に、で実行できる属性の文字列'delete(foo)'が残りますが、それを別のディレクティブ ボタンのクリックに関連付ける方法がわかりません。ng-click$parse(attrs.ngClick)(scope)

編集:これは、実装における私の現在の試みのフィドルです。問題は、関数に渡される変数が常に未定義であることです。

http://jsfiddle.net/UCtbj/2/

Edit2:更新された実装ですが、他のディレクティブ要素をターゲットにして2つのディレクティブをリンクする方法が特に好きではありません。

http://jsfiddle.net/UCtbj/3/

4

7 に答える 7

3

モーダル ウィンドウの最初の単純なサービス:

app.service('ConfirmService', function($modal) {
  var service = {};
  service.open = function (text, onOk) {
    var modalInstance = $modal.open({
      templateUrl: 'myModalContent.html',
      controller: 'ModalConfirmCtrl',
      resolve: {
        text: function () {
          return text;
        }
      }
    });

    modalInstance.result.then(function (selectedItem) {
      onOk();
    }, function () {
    });
  };

  return service;
})

app.controller('ModalConfirmCtrl', function ($scope, $modalInstance, text) {

  $scope.text = text;

  $scope.ok = function () {
    $modalInstance.close(true);
  };

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
});

次に、それを使用する簡単なディレクティブ:

app.directive('confirm', function(ConfirmService) {
    return {
        restrict: 'A',
        scope: {
            eventHandler: '&ngClick'
        },
        link: function(scope, element, attrs){
          element.unbind("click");
          element.bind("click", function(e) {
            ConfirmService.open(attrs.confirm, scope.eventHandler);
          });
        }
    }
});

そして、ここに行きます:

<button ng-click="test(12)" confirm='Are you sure?'>Button</button>

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

于 2015-02-03T17:51:46.140 に答える
1

これは、そのための優れたディレクティブですngBootbox。見てみな。

<button class="btn btn-lg btn-primary"
        ng-bootbox-title="A cool title!"
        ng-bootbox-custom-dialog="Some custom text"
        ng-bootbox-buttons="customDialogButtons"
        ng-bootbox-class-name="some-class">
    Custom dialog
</button>

<script>
    $scope.customDialogButtons = {
        warning: {
            label: "Warning!",
            className: "btn-warning",
            callback: function() { $scope.addAction('Warning', false); }
        },
        success: {
            label: "Success!",
            className: "btn-success",
            callback: function() { $scope.addAction('Success!', true) }
        },
        danger: {
            label: "Danger!",
            className: "btn-danger",
            callback: function() { $scope.addAction('Danger!', false) }
        },
        main: {
            label: "Click ME!",
            className: "btn-primary",
            callback: function() { $scope.addAction('Main...!', true) }
        }
    };
    </script>

デモ

ngBootbox

于 2015-04-13T13:27:49.580 に答える
1

ボタンを次のようにマークアップできるようにするには

<button type="button" ng-click="deleteItem(drink)" ng-confirm="Are you sure you want to delete '{{drink.name}}'">Delete</button>

次のディレクティブを記述できます。

  • ngClickのクリック ハンドラが実行される前に、クリック イベントをインターセプトします。
  • ダイアログを開きます ($modal削除された ではなくを使用$dialog)
  • ダイアログclose(成功として扱われる)ngClickで、要素の属性で指定された関数を実行します。

前の回答に基づいてコードを作成すると、次のように実行できます。

app.directive('ngConfirm', function($modal, $parse) {
  return {
    // So the link function is run before ngClick's, which has priority 0
    priority: -1,

    link: function(scope, element, attrs) {
      element.on('click', function(e) {
        // Don't run ngClick's handler
        e.stopImmediatePropagation();

        $modal.open({
          templateUrl: 'ng-confirm-template',
          controller: 'ngConfirmController',
          resolve: {
            message: function() {
              return attrs.ngConfirm;
            }
          }
        }).result.then(function() {
          // Pass original click as '$event', just like ngClick
          $parse(attrs.ngClick)(scope, {$event: e});
        });
      });
    }
  };
});

シンプルなコントローラーが必要です:

app.controller('ngConfirmController', function($scope, $modalInstance, message) {
  $scope.message = message;

  $scope.yes = function() {
    $modalInstance.close();
  };

  $scope.no = function() {
    $modalInstance.dismiss();
  };
});

ダイアログのテンプレート:

<script type="text/ng-template" id="ng-confirm-template">
  <div class="modal-body">
    <p>{{message}}</p>
  </div>
  <div class="modal-footer">
    <button class="btn btn-link pull-left" ng-click="no()">No</button>
    <button class="btn btn-primary pull-right" ng-click="yes()">Yes</button>
  </div>
</script>

これはhttp://plnkr.co/edit/Gm9lFsGb099w6kCMQoVY?p=previewで実行されているのを見ることができます

編集:ダイアログの表示でスクロールバーが表示/非表示になることなく、プランカーリンクを例に変更しました

于 2015-02-01T10:36:09.387 に答える
0

わかりました、これが私が最終的に行ったものです

1) ダイアログのサービスを作成する

app.service('dialogModal', [
    '$modal', function($modal) {
    return function(message, title, okButton, cancelButton) {

      okButton = okButton === false ? false : (okButton || 'Yes');
      cancelButton = cancelButton === false ? false : (cancelButton || 'No');

      var modalInstance = $modal.open({        
        templateUrl: '/templates/deletePrompt.html',
        controller: ModalInstanceCtrl,
        resolve: {
          settings: function() {
            return {
              modalTitle: title,
              modalBody: message,
              okButton: okButton,
              cancelButton: cancelButton
            };
          }
        }
      });
      // return the modal instance
      return modalInstance;
    }
  }
]);

2)コントローラーを作成し、モデルインスタンスを渡します

var ModalInstanceCtrl = function ($scope, $modalInstance, settings) {

  angular.extend($scope, settings);

  $scope.ok = function () {
    $modalInstance.close(true);
  };

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
};

3) リンクをヘッダーに含めて、デフォルトのスタイルを適用する

<link data-require="bootstrap-css@3.x" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />

4) 自分の css でスタイリングを上書きしました

5)これが私の削除プロンプトテンプレートです

<div id="overlayClearMainDiv" class="dialog-modal">
  <div id="overlayClearText">
    <span>{{modalBody}}</span>
  </div>
  <div id="overlayClearButton">
    <button id="overlayClearYesButton" class="confirmButton" type="button" ng-click="ok()" ng-show="okButton">{{okButton}}</button> 
    <button class="confirmButton-white" ng-click="cancel()" ng-show="cancelButton">{{cancelButton}}</button> 
  </div>
</div>
于 2015-02-03T14:39:24.093 に答える