来自控制器的Angular调用指令

Dom*_*ann 6 angularjs angularjs-directive

我有以下指令用于显示弹出窗口以确认单击时执行函数.

现在我想在我的控制器中使用它来显示一个弹出窗口,如果一个对象的属性已被更改,并且用户想要更改位置而不保存之前的对象.那可能吗?

angular.module('app.confirm', [
    'ui.bootstrap',
    'template/modal/confirm.html',
])

.controller('ConfirmModalController', ['$scope', '$modalInstance', function($scope, $modalInstance) {
    $scope.confirm = function() {
        $modalInstance.close();
    };

    $scope.cancel = function() {
        $modalInstance.dismiss('cancel');
    };
}])

.directive('confirm', ['$modal', function($modal) {
    return {
        restrict: 'A',
        scope: {
            confirm: '&',
            title: '@confirmTitle',
            message: '@confirmMessage',
            confirmButtonText: '@confirmButtonText',
            cancelButtonText: '@cancelButtonText'
        },
        link: function(scope, element, attributes) {
            element.bind('click', function() {
                var modal= $modal.open({
                    controller: 'ConfirmModalController',
                    templateUrl: 'template/modal/confirm.html',
                    size: 'sm',
                    scope: scope
                });

                modal.result.then(function() {
                    scope.confirm();
                }, function() {
                    // Modal dismissed
                });
            });
        }
    };
}]);

angular.module('template/modal/confirm.html', []).run(['$templateCache', function($templateCache) {
    $templateCache.put(
        'template/modal/confirm.html',
        '<div class="modal-header" ng-show="title">' + 
            '<strong class="modal-title">{{title}}</strong>' + 
        '</div>' + 
        '<div class="modal-body">' +
            '{{message}}' + 
        '</div>' + 
        '<div class="modal-footer">' +
            '<a href="javascript:;" class="btn btn-link pull-left" ng-click="cancel()">{{cancelButtonText}}</a>' + 
            '<button class="btn btn-danger" ng-click="confirm()">{{confirmButtonText}}</button>' +
        '</div>'
    );
}]);
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用它:

<button 
    confirm="delete(id)" 
    confirm-title="Really?"
    confirm-message="Really delete?"
    confirm-button-text="Delete"
    cancel-button-text="Cancel"
    class="btn btn-danger"
>
    Delete
</button>
Run Code Online (Sandbox Code Playgroud)

mcc*_*inz 7

N0- $手表解决方案:

1.
为控制器提供一个回调函数,该回调函数接收指令中公开的接口.您的控制器会抓取界面并在其所需的脚本中使用它.简单,可以在任何现有指令上实现.

用于接口回调的Plnkr

  app.directive("simpleDialog",function(simpleDialog){
    return{
      template:"<button ng-click='open()'>open from directive</button>",
      scope:{
        onInit : "&onInit"
      },
      link: function(scope){
        scope.open = simpleDialog.open;
        scope.onInit({interface:{open:scope.open}});
      }
    }
  });
Run Code Online (Sandbox Code Playgroud)

更复杂但更好的模式......

2.
如果您希望制定一个也具有可编程接口的指令,那么我建议将该指令的核心实现为提供者.然后,您可以基于提供程序实现指令,如果您希望通过脚本完全访问相同的功能,则可以通过将其注入控制器直接在提供程序上运行.

这是ngDialog遵循的实施策略

此外,在创建确认对话框时,您会发现此模式很有用,因为您的open方法可以返回一个可以由对话框解决或拒绝的promise,允许您的控制器根据promise做出响应.

PLNKR DEMO

<!DOCTYPE html>
<html>

  <head>
    <script data-require="angular.js@*" data-semver="1.3.0" src="//code.angularjs.org/1.3.0/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    
  </head>

  <body ng-controller="myCtrl">
  
    <h1>Exposing a  Directive interface to a controller</h1>
    <div simple-dialog on-init="initCallback(interface)"></div>
    <p><button ng-click="open()">Open from controller</button></p>
    <p><button ng-click="open2()">Open from Exposed interface</button></p>
    
    <script>
      
      
      var app = angular.module("app",[]);
      
      app.controller("myCtrl",function(simpleDialog,$scope){
        $scope.open = simpleDialog.open;
        $scope.open2 = function(){
          this.interface.open();
        }
        $scope.initCallback = function(interface){
          this.interface = interface;
        }
      });
      
    
      app.provider("simpleDialog",function(){
        
        this.$get = function(){
          
          var publicMethods={
            open:function(){
              alert("Impelment Dialog Here");
            }
          }
          
          return publicMethods;
          
        }
      });
      
      app.directive("simpleDialog",function(simpleDialog){
        return{
          template:"<button ng-click='open()'>open from directive</button>",
          scope:{
            onInit : "&onInit"
          },
          link: function(scope){
            scope.open = simpleDialog.open;
            scope.onInit({interface:{open:scope.open}});
          }
        }
      });
      
      angular.bootstrap(document,["app"]);
      
    </script>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)


Jos*_*seM 0

您可以观察指令中范围属性的变化。

例如,添加一个confirm-show-when

<button 
    confirm="delete(id)" 
    ...
    confirm-show-when="state.showConfirmDialog"
    ...
>
    Delete
</button>
Run Code Online (Sandbox Code Playgroud)

将其添加到您的指令定义中

.directive('confirm', ['$modal', function($modal) {
    return {
        restrict: 'A',
        scope: {
            confirm: '&',
            title: '@confirmTitle',
            message: '@confirmMessage',
            confirmButtonText: '@confirmButtonText',
            cancelButtonText: '@cancelButtonText',
            showWhen: '=confirmShowWhen'
        },
        link: function(scope, element, attributes) {
            var showModal = function() {
                var modal= $modal.open({
                    controller: 'ConfirmModalController',
                    templateUrl: 'template/modal/confirm.html',
                    size: 'sm',
                    scope: scope
                });

                modal.result.then(function() {
                    scope.confirm();
                }, function() {
                    // Modal dismissed
                    // set showWhen back to false
                    scope.showWhen = false;
                });
            };
            element.bind('click', showModal);
            scope.$watch('showWhen', function(newVal) {
                if (newVal) {showModal()};
            });
        }
    };
}]);
Run Code Online (Sandbox Code Playgroud)

showConfirmDialog当你想显示它时,只需在你的控制器中将其设置为 true 即可。

// controller code
// set up the state object so we use the 'dot' notation
$scope.state = { showConfirmDialog: false };
// other controller code
if (userWantsToDelete) {
    $scope.state.showConfirmDialog = true;
}
Run Code Online (Sandbox Code Playgroud)