1

In Angular and using Bootstrap 3.0, I would like to open a modal window to confirm an action where the modal action button continues to complete the request. I have put the modal code into a directive. I have the modal working but changing the data-ng-click attribute doesn't seem to wire up into Angular. I am not interested in using AngularUI.

My question - how do I use a directive (single instance on a page) and pass it a method to execute from "outside of the directive" calls?

I am creating a generic modal directive for confirmation e.g. confirm delete via a modal.
I need to supply an id, title, content (rendered as transclude) delete button text, delete button action << this is what I am struggling with.

So to summarise, I have the modal box and I open the modal from a repeated table button delete click event. The modal opens but does not execute the confirmed action button code.

On the page I have a single modal directive call (sets up a simple initially hidden modal):

   <modal-confirm modalid="myModalTest" 
title="Confirm delete" actiontext="Confirm delete">
Are you sure you wish to delete this application?
</modal-confirm>

Which is called from a repeated button, the attribute "data-post-event-method" contains the action method I wish to call:

   <a id="applicationDeleteItem_{{app.applicationID}}" 
data-ng-click="OpenModal($event, 'myModalTest')"  
data-post-event-method="dosomething({{app.applicationID}});" 
class="btn btn-primary btn-xs">Delete?</a>

Note: the OpenModal method here is introduced from the directive using scope.$parent - could probably use a better suggestion here too, anyway I am trying to avoid writing UI code in the controller.

In my controller I have only the action code:

$scope.dosomething = function (p) {
            alert('perform the delete' + p);
            console.log(p);
        };

Here is my modal confirm directive:

define(['angular'], function (angular) {
    'use strict';

    return angular.module('dsAppCore.Directives').directive('modalConfirm', function ($timeout, $compile) {
        var t = "";

     t += '  <!-- Modal -->                                                                                                               ';
     t += '  <div class="modal fade" id="{{modalid}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">      ';
     t += '    <div class="modal-dialog">                                                                                                 ';
     t += '      <div class="modal-content">                                                                                              ';
     t += '        <div class="modal-header">                                                                                             ';
     t += '          <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>                         ';
     t += '          <h4 class="modal-title">{{title}}</h4>                                                                             ';
     t += '        </div>                                                                                                                 ';
     t += '        <div class="modal-body">                                                                                              ';
     t += '            <div ng-transclude></div>                                                                                           ';
     t += '        </div>                                                                                                                 ';
     t += '        <div class="modal-footer">                                                                                             ';
     t += '          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>                                    ';
     t += '          <button type="button" id="{{modalid}}_confirmClickEvent" class="btn btn-primary" data-ng-click="" >{{actiontext}}</button>                                                  ';
     t += '        </div>                                                                                                                 ';
     t += '      </div><!-- /.modal-content -->                                                                                           ';
     t += '    </div><!-- /.modal-dialog -->                                                                                              ';
     t += '  </div><!-- /.modal -->                                                                                                       ';

     return {
         restrict: 'E',
         transclude: true,

         scope: {
             title: '@',
             modalid: '@',
             actiontext: '@'
         },
         link: function (scope, element, attrs) {

             scope.$parent.OpenModal = function (e, modalId) {
                 var self = this;

                 // Open the modal
                 $('#' + modalId).modal('toggle');

                 // Get a reference to the UI element that clicked the item
                 var elemID = angular.element(e.srcElement).attr('id');

                 // Extract the post event action method call(s)
                 var postEventMethod = angular.element(e.srcElement).attr("data-post-event-method");

                 // Update the action button with the calls

                 var some = { m: postEventMethod }

                // $timeout(function () {
                 var elemIDAction = angular.element($("#" + scope.modalid + "_confirmClickEvent"));


                 elemIDAction.attr("data-ng-click", some.m);

                 // This not good-  it causes the delete action to be called x times 
                 // where x is the number of times the window has been opened.
                 $compile(elemIDAction)(scope.$parent);

             };
         },
            controller: function ($scope, $element) {

            },
            template: t
        };
    });
});

So in short - while I can open the modal box, I cannot assign a method to the ng-click event. Using jquery to replace the text results in nothing happening when the button is clicked. I can't pass in the method in the directive declaration because this modal is served by many external to the directive calls.

4

1 回答 1

1

好的,我解决了问题 - 我创建了一个角度服务并将一些代码移动到控制器:

工厂:

define(['angular'], function (angular) {
    'use strict';

    return angular.module('dsAppCore.Factories').factory('coreModalConfirm', ['$window', 'coreSerErrorReporter', 'coreSerLogging',
                                                    function ($window, coreSerErrorReporter, coreSerLogging) {
        var self = this;

        var confirm = function (message) {
            return $window.confirm(message);
        };

        var showModal = function (modalId)
        {
            $('#' + modalId).modal('toggle');
        }

        return {
            confirm: confirm,
            showModal: showModal
        };
    }]);

});

控制器:

 $scope.confirmDeleteApp = function (appID)
        {
            coreModalConfirm.showModal("myModalTest");
            $scope.appToDeleteIfConfirmed = appID;
        }

        $scope.deleteApp = function ()
        {
            alert($scope.appToDeleteIfConfirmed);

        }

我的模态指令在行动:

<modal-confirm data-modal-confirm-action="deleteApp()" data-modal-title="Confirm - delete application?" data-modal-content="Are you sure you want to delete this application?" data-modal-action-text="Delete application" ></modal-confirm>

以及 HTML 页面上的主要调用链接按钮(在 ng-repeat 内)

 <a id="applicationDeleteItem_{{app.applicationID}}" data-ng-click="confirmDeleteApp(app.applicationID)" class="btn btn-primary btn-xs">Delete?</a>

为了使这个更通用,我还有一些事情要做。

于 2013-10-05T14:16:18.480 回答