what is the most elegant way of opening a pop up window with angular and receiving data from it on the parent

StackOverflow https://stackoverflow.com/questions/20670588

Pregunta

I currently have this controller to open it:

marketApp.controller('loginCtrl', ['$scope', '$http', 'userService', function ($scope,      $http, userService) {

$scope.openPopUp = function () {
    if( !userService.popupWin || userService.popupWin.closed ) {
        userService.popupWin = window.open('http://example/auth/enter','','toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=400, height=400');
    } else userService.popupWin.focus();
}

}]);

But I still haven't figured out the bet way to retrieve data from it using only angular.js

¿Fue útil?

Solución

If you don't have to support old browsers, you can use the postMessage API. It allows you to listen for messages in your parent code, and then send messages in your child code.

//Parent Window
window.addEventListener('message', function(message){ /*some code here*/ });

//Child Window
window.parent.postMessage({"foo":"bar"});

This is how you can chat like this.

Otros consejos

I just noticed you said with "only angularjs". My answer uses bootstrap for ease of making a popup on the same page. You can write your own HTML/CSS to mimic bootstrap if you don't want to use other frameworks. The concept still applies.

I put together a jsfiddle that uses twitter bootstrap for its modal (note Twitter Bootstrap also requires jQuery). This way you can maintain SPA architecture. http://jsfiddle.net/patrickdubs/UHg95/8/

I created a directive for the modalWindow that will augment functions onto the userService. This way, each individual controller can call popupWin on the userService. I'm only demonstrating with "First Name" field, but this can easily be extended to meet whatever needs you have.

marketApp.directive("modalWindow", ["userService", function (userService) {
    var isOpen = false;
    return {
        restrict: "AE",
        replace: "true",
        scope: {user-data: '='},
        template: '<div class="modal fade"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><h4 class="modal-title">User Service</h4></div><div class="modal-body"><p>First Name: <input type="text" ng-model="data.firstName" /></p></div><div class="modal-footer"><button type="button" class="btn btn-default" ng-click="closeWin()">Close</div></div></div></div>',
        link: function (scope, element, attrs) {
            scope.closeWin = function () {
                if (!isOpen) {
                    return;
                }

                element.modal("hide");
                scope.userData.firstName = scope.data.firstName;
                isOpen = false;
            }

            userService.popupWin = function () {
                if (isOpen) {
                    return;
                }

                element.modal("show");

                isOpen = true;
            }

            userService.isOpen = function () {
                  return isOpen;   
            }
        }
    }
}]);

Then in your controller, just create an object to pass to user-data in the modal:

marketApp.controller('loginCtrl', ['$scope', '$http', 'userService', function ($scope,      $http, userService) {

$scope.d = {};

$scope.openPopUp = function () {
    if( !userService.isOpen() ) {
        userService.popupWin();
    }
}

}]);

And the HTML:

<div ng-app="marketApp" ng-controller="loginCtrl">
    <div modal-window user-data="d"></div>
    <button ng-click="openPopUp()">Open Popup</button>

    <p>First Name From Popup: {{d.firstName}}</p>
</div>

Referrence : http://angular-ui.github.io/bootstrap/

Html page code

       <!doctype html>
       <html ng-app="ui.bootstrap.demo">
       <head>
       <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.13/angular.js"></script>
       <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.0.js"></script>
       <script src="demo.js"></script>
       <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
      </head>
      <body>
        <div>
        <button class="btn btn-default" ng-click="open('lg')">Large modal</button>
      </div> 

      </body>
      </html>   

PopUp Template

myModalContent.html

<div class="modal-header">
        <h3 class="modal-title">I'm a modal!</h3>
    </div>
    <div class="modal-body">
        <ul>
            <li ng-repeat="item in items">
                <a ng-click="selected.item = item">{{ item }}</a>
            </li>
        </ul>
        Selected: <b>{{ selected.item }}</b>
    </div>
    <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>

demo.js code

angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl',
  function ($scope, $modal, $log){
    $scope.items = ['item1', 'item2', 'item3'];


   $scope.open = function (size) {

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

modalInstance.result.then(function (selectedItem) {
  $scope.selected = selectedItem;
}, function () {
  $log.info('Modal dismissed at: ' + new Date());
});
};
 });

Controller code popup template

  angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl',         

 function ($scope, $modalInstance, items)
 {
         $scope.items = items;
         $scope.selected = {
         item: $scope.items[0]
};

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

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
    };
    });
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top