53 votes

Problème de portée dans AngularJS avec AngularUI Bootstrap Modal

plunker: http://plnkr.co/edit/wURNg8ByPYbEuQSL4xwg

exemple.js:

 angular.module('plunker', ['ui.bootstrap']);
  var ModalDemoCtrl = function ($scope, $modal) {

  $scope.open = function () {
    var modalInstance = $modal.open({
      templateUrl: 'modal.html',
      controller: 'ModalInstanceCtrl'
    });
  };
};

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

  $scope.ok = function () {
    alert($scope.text);
  };

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

index.html:

 <!doctype html>
<html ng-app="plunker">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script>
    <script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.6.0.js"></script>
    <script src="example.js"></script>
    <link href="http://stackoverflow.com//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
  </head>
  <body>

  <div ng-controller="ModalDemoCtrl">
    <button class="btn" ng-click="open()">Open me!</button>
    <div ng-show="selected">Selection from a modal: {{ selected }}</div>
  </div>
 </body>
</html>
 

modal.html:

 <div class="modal-header">
    <h3>I'm a modal!</h3>
</div>
<textarea ng-model="text"></textarea>
<div class="modal-footer">
    <button class="btn btn-primary" ng-click="ok()">OK</button>
    <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
 

Pourquoi je ne peux pas obtenir le $ scope.text défini dans ModalInstanceCtrl, même si je peux utiliser $ scope.ok et $ scope.cancel?

72voto

CodeHater Points 13377

On dirait un problème de portée. Je l'ai fait fonctionner comme ceci:

 var ModalInstanceCtrl = function ($scope, $modalInstance) {
    $scope.input = {};
    $scope.ok = function () {
        alert($scope.input.abc);
    };

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

HTML:

 <textarea ng-model="input.abc"></textarea>
 

16voto

gertas Points 7113

Les modaux de l'interface utilisateur angulaire utilisent la transclusion pour attacher un contenu modal, ce qui signifie que toutes les nouvelles entrées de portée effectuées dans modal sont créées dans une portée enfant.

Vous devez utiliser l'héritage et initialiser les entrées vides text dans parent $scope ou vous pouvez explicitement attacher l'entrée à la portée parent:

 <textarea ng-model="$parent.text"></textarea>
 

3voto

笑笑十年 Points 11

Dans le code source de modal ui-bootstrap:

 .directive('modalWindow', ['$modalStack', '$timeout', function ($modalStack, $timeout) {
return {
  restrict: 'EA',
  scope: {
    index: '@',
    animate: '='
  },
  replace: true,
  transclude: true,
  templateUrl: function(tElement, tAttrs) {
    return tAttrs.templateUrl || 'template/modal/window.html';
  },
 

et tabke regardons le code source du template - window.html:

 <div tabindex="-1" role="dialog" class="modal fade" ng-class="{in: animate}" ng-style="{'z-index': 1050 + index*10, display: 'block'}" ng-click="close($event)">
<div class="modal-dialog" ng-class="{'modal-sm': size == 'sm', 'modal-lg': size == 'lg'}"><div class="modal-content" modal-transclude></div></div>
 

il y a une directive modal-transclude , le contenu de votre boîte de dialogue y insérera, c'est son code source:

 .directive('modalTransclude', function () {
return {
  link: function($scope, $element, $attrs, controller, $transclude) {
    $transclude($scope.$parent, function(clone) {
      $element.empty();
      $element.append(clone);
    });
  }
};
 

})

OK, jetons maintenant un coup d'œil au document officiel de $ compile:

 Transclusion Functions

When a directive requests transclusion, the compiler extracts its contents and provides 
a transclusion function to the directive's link function and controller. 
This transclusion function is a special linking function that will return the compiled 
contents linked to a **new transclusion scope.**
 

transclude créera une nouvelle portée de la portée du contrôleur

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X