1

I know it might be a simple question, but I'm frustrated here, and I can't make it work. I'm new to AngularJS, and I'm trying to implement a modal dialog (or find one) with these conditions:

  1. Dialog content might come from anywhere—a string template, a script template, or a template from a URL
  2. Dialog title and actions will come from the caller, not the callee. In other words, the parent scope decides the title and which action buttons should exist in the modal dialog (many dialogs I found encapsulate the title and action buttons in the template itself, for example this one)
  3. Content of the template should be totally independent from parent scope (caller). In fact, it might not even be written in AngularJS. It might use jQuery.
  4. In case the loaded template is in AngularJS, it should encapsulate its controller. For example, ng-include doesn't like <script> tags.

    There is a workaround for it (here, here and here) but the idea of decorating a script tag with text/javascript-lazy is very smelly and dirty, let alone that I want the content HTML to be self-contained and executable in case it's not loaded as the content of an AngularJS modal dialog.

  5. Communication between the parent scope and the content should be done via a common contract (JavaScript events come to my mind)

I've tried ngDialog, but the problem is that the container should pass the controller to the loaded template. That's not what I want. In Bootstrap dialog also it seems that you have to pass the controller from the parent scope to the dialog content. This breaks the very notion of encapsulation. It's not desirable. Also, it's dependent on dialog result, which is not desirable either.

Nathan Arthur
  • 8,287
  • 7
  • 55
  • 80
Saeed Neamati
  • 35,341
  • 41
  • 136
  • 188

1 Answers1

0

I recommend use Angular-UI library. You can easy create any dialog a-la "Twitter Bootstrap":

Include js in your page head.

<script src="/desktop/libs/angular-bootstrap/ui-bootstrap.js"></script>
<script src="/desktop/libs/angular-bootstrap/ui-bootstrap-tpls.js}"></script>

Include modules at app initialization.

var Application = A.module('MyApp', [ 'ui.bootstrap', 'ui.bootstrap.modal' ]);

Inject in jour controller $modal:

(function (A){
    "use strict";
    A.module("MyApp").controller("OpenDlg", [ "$scope", "$modal", function($scope, $modal){
        $scope.openDlg = function(){
            $modal.open({
                controller : 'CategoryAddController',
                templateUrl : '/admindesktop/templates/category/add/'
            }).result.then(function(modalResult){
                console.log(modalResult);
            });
        };
    } ]);
}(this.angular));

For example, simple template for dialog:

<div class="modal-content">
    <div class="modal-header">
        <h4 class="modal-title text-center">Создание новой категории</h4>
    </div>
    <form class="modal-body form-horizontal" name="categoryForm">
       <div class="form-group">
           <label for="name" class="control-label col-xs-3">Название</label>
           <div class="col-xs-9">
               <input name='name' type="text" class="form-control" ng-model="category.name" maxlength=50 required ng-required="true"/>
           </div>
           <div class="row has-error" ng-show="errors.name">
               <p ng-repeat="error in errors.name">{{ error }}</p>
           </div>          
       </div>
       <div class="container-fluid" ng-show="errors.length > 0">
           <div class="row">
               <p class="text-center text-danger" ng-repeat="error in errors">{{ error }}</p>
           </div>
       </div>      
    </form>
    <div class="modal-footer">
        <button class="btn btn-primary" ng-click="save()" ng-disabled="categoryForm.$invalid">Сохранить</button>
        <button class="btn btn-default" ng-click="cancel()">Отмена</button>
    </div>
</div>

Main: controller for modal window:

(function(A) {
    "use strict";
    var app = A.module('MyApp');

    app.controller('CategoryAddController', [ '$scope', '$modalInstance', 'Category', 'growl', function($scope, $modalInstance, Category, growl) {

    $scope.save = function() {
        var category = new Category($scope.category);

        category.$save(function() {
            growl.success('Категория успешно создана');
            $modalInstance.close(true);
        }, function(response) {
            $scope.errors = response.data;
        });
    };

    $scope.cancel = function() {
        $modalInstance.close(false);
    };
    } ]);
}(this.angular));

I use Service for data changing between modal controller and parent scope:

(function(A){
    "use strict";
    A.module("MyApp").service('Storage', function(){
        return {
            storedData: undefined
        };
    });
}(this.angular));

In parent scope:

Storage.storedData = ...; //For example, selected row of table

In modal controller:

$scope.item = Storage.storedData; //Selected row of table

Also angular have special module type, value.

Dunaevsky Maxim
  • 3,062
  • 4
  • 21
  • 26