ANGULARJS DIRECTIVE FOR SHOWING CONTENT IN A NEW WINDOW

http://blog.softnauts.com/2014/03/18/building-angular-directive-that-shows-content-in-new-window/

To make our life easier, we decided to write the directive for displaying its content in a new window. 
We want to preserve bidirectional data binding between parent and child windows. 
Also, after removing the directive from the parent window DOM - the child window should disappear.

THE GOAL

You may see exactly what we want on jsFiddle (remember to allow it to open popups).

Sample code :

<new-window> 
    {{code}} 
    <input ng-model="code" />
</new-window>

<div> 
    {{code}} 
    <input ng-model="code"/>
</div>

This code should open a new window with input and text, in a parent window should also be visible input and text, changing input value in any window should be propagated over application.

Another example:

<input ng-model="newItem" />
<button ng-click="items.push(newItem);">push!</button>
<button ng-click="items = [];">clear</button>    

<div ng-repeat="code in items">
    {{code}}
</div>
<new-window ng-repeat="code in items">
    {{code}} 
    <input ng-model="code" />
</new-window>

We should see the parent window input, and we should be able to add input's content to an array by clicking "push" button. We also should see the button for cleaning an array, and finally all the elements of an array... After cleaning the array all children windows should disappear, and after adding a new element to the array, another window should appear.

With windows displayed as a result of displaying items from the array, bidirectional data binding is not preserved - do you know why? :)

READY DIRECTIVE CODE

Let's see how the final directive looks like, then we'll discuss each part.

app.directive('newWindow', ['$window', '$compile',
  function($window, $compile) {
    return {
      restrict: 'EA',
      link: function($scope, $element, attr) {
        $element.on('$destroy', function() {
          $scope.window.close();
        });
      },
      controller: function($scope, $element) {
        $scope.window = $window.open('', '_blank');
        angular
          .element($scope.window.document.body)
          .append($compile($element.contents())($scope));
      }
    }
  }
]);
OPENING WINDOWS AND BINDING DATA
controller: function($scope, $element) {
    $scope.window = $window.open('', '_blank');
    angular
      .element($scope.window.document.body)
      .append($compile($element.contents())($scope));
}

Open a new window, saving its handle in our local scope - will be essential if later we would like to close the window. The most interesting in this part is the append method parameter , which fill the newly opened window with its content. We use here the service $compile , which does not work as described in the documentation... This call should return a string with the template compiled in our scope, but it rather returns a reference to the DOM object, which will later be compiled... For our needs, it's even better - angular preserves data binding, and we display the object in a new window.

CLOSE THE WINDOW
link: function($scope, $element, attr) {
  $element.on('$destroy', function() {
      $scope.window.close();
  });
}

If our directive is removed from the DOM tree, for example, by deleting the item from the table ng-repeat iterates, the window should disappear. Window closing code should exists in handler of $destroy event, which is emitted by the angular before the destruction of the directive. In such situation we simply close the window whose handle we saved in the local scope.

STYLING
new-window { display: none; }

We want to display the directive in a new window, while it should stay invisible in parent window.

WHAT DO WE GAIN

New window does not need to know anything about JavaScript , or about Angular , because the whole logic remains in the parent window. We don't need to think about it, and the only thing we need to do is to build content of new window.

WHAT DO WE LOSE

It's harder to prepare code for new window, as it's not enough to simply write it somewhere and click "refresh" in the browser. Debugging may also not be as easy as it was in a single-window app.

Jan Machalica

Orginally posted on Janek's Wiki

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值