Problema de escopo no AngularJS usando o AngularUI Bootstrap Modal

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

example.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:

          
Selection from a modal: {{ selected }}

modal.html:

    

Por que não consigo obter o $ scope.text definido em ModalInstanceCtrl, mesmo que eu possa usar $ scope.ok e $ scope.cancel?

Parece um problema de escopo. Eu tenho que trabalhar assim:

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

HTML:

  

Atualização de novembro de 2014: o problema é corrigido com o 0.12.0 – o escopo da transclusão é mesclado com o escopo do controlador. Não há necessidade de fazer nada. Apenas fique com:

  

Antes de 0.12.0:

Os modais Angular-UI estão usando a transclusão para append o conteúdo modal, o que significa que quaisquer novas inputs de escopo feitas dentro do modal são criadas no escopo filho.

Você deve usar inheritance e inicializar a input de text vazia no $scope pai $scope ou append explicitamente a input ao escopo pai:

  

Vou tentar explicar o motivo. código-fonte modal modal do 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'; }, 

e o código fonte do modelo – window.html:

  

existe uma diretiva modal-transclude , o conteúdo do seu diálogo será inserido nele, é o código fonte:

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

})

agora dê uma olhada no doc oficial 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 irá criar um novo escopo de escopo do controlador