wake-up-neo.com

Schließen von Twitter Bootstrap Modal von Angular Controller

Ich habe ein modales Fenster, das ich verwende, um Benutzern ein Formular zu präsentieren. Sie geben die Informationen ein und drücken dann eine Taste, die einen Klick enthält. Der Server verarbeitet die Anfrage und sendet eine Antwort zurück. Wenn die Antwort erfolgreich ist, möchte ich das modale Fenster von der Steuerung aus schließen. Wie kann das erreicht werden?

Das Modal ist teilweise auf einer anderen Seite enthalten

Hauptseite:

<!-- main content -->
<p>Foo</p>
<!-- angular directive -->
<foo-directive></foo-directive>

Inhalt dieser Richtlinie:

<div ng-controller="FooCtrl">
    <ul class="thumbnails">
        <li class="span3 tile tile-white" ng-repeat="foo in model.foo">
            <div>
                {{foo.bar}}
            </div>
            <div>
                ({{foo.bam}})
            </div>
            <div>
                <a data-toggle="modal" href="#myModal"><img src="{{foo.imgPath}}"></a>
            </div>
        </li>
    </ul>
    <!-- foo modal partial included by ejs -->
    <% include foo_modal.ejs %>
</div>

Modales Markup:

<div id="fooModal" class="modal hide fade in" style="display: none; ">
    <div class="modal-header">
        <a class="close" data-dismiss="modal">×</a>
        <h3>New Device</h3>
    </div>
    <div class="modal-body">
        <h4>Foo Modal</h4>
        <div ng-controller="FooCtrl">
            <form name="fooFrm">
                <input id="email" type="email" class="input-medium" ng-model="fooEmail"
                       placeholder="Email">
                <button class="btn btn-primary btn-small"
                        ng-click="doFoo({email:fooEmail})">Email Link</button>
            </form>
        </div>
    </div>
    <div class="modal-footer">
        <a href="#" class="btn" data-dismiss="modal">Close</a>
    </div>
</div>

Controller-Code:

functionFooCtrl($scope, FooService) {


    $scope.doFoo= function (email) {
       FooService.save({email:email.fooEmail}) {
            alert('Request successful');
            //TODO close Twitter bootstrap modal named fooModal here
        },
            function (err) {
                alert('Your request bonked, sorry');
                //TODO close Twitter bootstrap modal named fooModal here
            });
        }
    };

Was ist der richtige Weg, um die Modal von der Steuerung in den Erfolgs- und Fehlerfunktionen zu schließen?

Danke im Voraus,

40
binarygiant

Hast du dir angle-ui bootstrap angesehen? Es gibt eine Direktive Dialog (ui.bootstrap.dialog), die recht gut funktioniert. Sie können den Dialog während des Rückrufs winkelmäßig schließen (wie im Beispiel):

$scope.close = function(result){
  dialog.close(result);
};

Aktualisieren:

Die Richtlinie wurde seitdem in Modal umbenannt.

21
Foo L

Dasselbe können wir auch ohne Winkel-Ui erreichen. Dies kann unter Verwendung von Winkelanweisungen erfolgen.

Fügen Sie zuerst die Direktive zum Modal hinzu.

<div class="modal fade" my-modal ....>...</div>

Erstellen Sie eine neue Winkelrichtlinie:

app.directive('myModal', function() {
   return {
     restrict: 'A',
     link: function(scope, element, attr) {
       scope.dismiss = function() {
           element.modal('hide');
       };
     }
   } 
});

Rufen Sie jetzt die Methode dismiss () von Ihrem Controller auf.

app.controller('MyCtrl', function($scope, $http) {
    // You can call dismiss() here
    $scope.dismiss();
});

Ich bin noch in meinen frühen Tagen mit eckigen Js. Ich weiß, dass wir das DOM in den Controllern nicht manipulieren sollten. Ich habe also die DOM-Manipulation in der Direktive. Ich bin mir nicht sicher, ob das genauso schlimm ist. Wenn ich eine bessere Alternative habe, werde ich sie hier posten.

Wichtig ist, dass wir nicht einfach ng-hide oder ng-show in der Ansicht verwenden können, um die Modalität auszublenden oder anzuzeigen. Das versteckt einfach die modale und nicht die modale Kulisse. Wir müssen die Instanzmethode modal () aufrufen, um das Modal vollständig zu entfernen. 

49
isubuz

Sie können es so machen:

angular.element('#modal').modal('hide');
33
Jonathan Flores

Hier ist eine wiederverwendbare Angular-Direktive, die einen Bootstrap-Modal ein- und ausblenden kann.

app.directive("modalShow", function () {
    return {
        restrict: "A",
        scope: {
            modalVisible: "="
        },
        link: function (scope, element, attrs) {

            //Hide or show the modal
            scope.showModal = function (visible) {
                if (visible)
                {
                    element.modal("show");
                }
                else
                {
                    element.modal("hide");
                }
            }

            //Check to see if the modal-visible attribute exists
            if (!attrs.modalVisible)
            {

                //The attribute isn't defined, show the modal by default
                scope.showModal(true);

            }
            else
            {

                //Watch for changes to the modal-visible attribute
                scope.$watch("modalVisible", function (newValue, oldValue) {
                    scope.showModal(newValue);
                });

                //Update the visible value when the dialog is closed through UI actions (Ok, cancel, etc.)
                element.bind("hide.bs.modal", function () {
                    scope.modalVisible = false;
                    if (!scope.$$phase && !scope.$root.$$phase)
                        scope.$apply();
                });

            }

        }
    };

});

Verwendungsbeispiel 1 - dies setzt voraus, dass Sie das Modal anzeigen möchten - Sie können ng-if als Bedingung hinzufügen

<div modal-show class="modal fade"> ...bootstrap modal... </div>

Verwendungsbeispiel Nr. 2 - Hierbei wird ein Winkelausdruck im Attribut Modal-visible verwendet

<div modal-show modal-visible="showDialog" class="modal fade"> ...bootstrap modal... </div>

Ein anderes Beispiel - Um die Controller-Interaktion zu demonstrieren, können Sie dem Controller so etwas wie dieses hinzufügen. Nach 2 Sekunden wird der Modal angezeigt und nach 5 Sekunden ausgeblendet.

$scope.showDialog = false;
$timeout(function () { $scope.showDialog = true; }, 2000)
$timeout(function () { $scope.showDialog = false; }, 5000)

Ich bin spät dran, um zu dieser Frage beizutragen - diese Richtlinie wurde hier für eine andere Frage erstellt. Einfache Winkelrichtlinie für Bootstrap Modal

Hoffe das hilft.

5
Ender2050

Sie können data-dismiss = "modal" zu Ihren Tastenattributen hinzufügen, die die Funktion anglejs aufrufen.

Sowie;

<button type="button" class="btn btn-default" data-dismiss="modal">Send Form</button>
1
maskapsiz

Ich habe die Antwort von @isubuz und diese Antwort von @Umur Kontacı auf Attribut-Direktiven in eine Version remixt, in der Ihr Controller keine DOM-ähnliche Operation wie "demiss" nennt, sondern versucht, dies zu tun mehr MVVM-Stil, setzen Sie eine boolesche Eigenschaft isInEditMode. Die Ansicht wiederum verknüpft diese Informationen mit der Attributdirektive, mit der das Bootstrap-Modal geöffnet/geschlossen wird.

var app = angular.module('myApp', []);

app.directive('myModal', function() {
   return {
     restrict: 'A',
     scope: { myModalIsOpen: '=' },
     link: function(scope, element, attr) {
       scope.$watch(
         function() { return scope.myModalIsOpen; },
         function() { element.modal(scope.myModalIsOpen ? 'show' : 'hide'); }
       );
     }
   } 
});

app.controller('MyCtrl', function($scope) {
  $scope.isInEditMode = false;
  $scope.toggleEditMode = function() { 
    $scope.isInEditMode = !$scope.isInEditMode;
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Twitter-bootstrap/3.3.6/js/bootstrap.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/Twitter-bootstrap/3.3.6/css/bootstrap.css" rel="stylesheet"/>

<div ng-app="myApp" ng-controller="MyCtrl as vm">

<div class="modal fade" my-modal my-modal-is-open="isInEditMode">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-body">
        Modal body! IsInEditMode == {{isInEditMode}}
      </div>
      <div class="modal-footer">
        <button class="btn" ng-click="toggleEditMode()">Close</button>
      </div>
    </div>
  </div>
</div>

<p><button class="btn" ng-click="toggleEditMode()">Toggle Edit Mode</button></p> 
<pre>isInEditMode == {{isInEditMode}}</pre>
  
</div>

0
Jeroen