2014-10-30 101 views
5

我有以下指令來顯示彈出式菜單,以確認點擊時功能的執行。來自控制器的角度呼叫指令

現在我想在我的控制器中使用它來顯示彈出式菜單,如果對象的屬性已更改,並且用戶希望在不保存對象之前更改位置。那可能嗎?

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>' 
    ); 
}]); 

您可以使用它像:

<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> 
+0

你可以實現你的指令的控制器供應商。您的指令然後將使用提供者來實現它自己。它也允許你通過將你的提供者注入控制器來完全在腳本中創建相同的組件。 ngDialog以這種方式實現。 https://開頭github上。COM/likeastore/ngDialog – mccainz 2014-10-30 14:18:04

回答

0

你可以看在你的指令在作用域屬性的變化。

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

<button 
    confirm="delete(id)" 
    ... 
    confirm-show-when="state.showConfirmDialog" 
    ... 
> 
    Delete 
</button> 

將它添加到您的指令定義

.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()}; 
      }); 
     } 
    }; 
}]); 

而在你的控制器只需設置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; 
} 
7

N0- $腕錶的解決方案:


與接收您的指令暴露接口的回調提供您的控制器。您的控制器抓取接口並在腳本中使用它,但它需要。簡單,可以在任何現有的指令上實現。

Plnkr for interface callback

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}}); 
     } 
    } 
    }); 

要複雜得多,但一個很好的模式...

2.
如果你希望做一個指令,它也有一個可編程的接口,那麼,我建議實施該指令的核心是提供者。然後,您可以基於提供者實現您的指令,並且在希望通過腳本完全訪問相同功能的情況下,您可以直接在提供者上操作,方法是將其注入到控制器中。

這是實現策略之後ngDialog

而且,你要創建一個確認對話框,你會發現這種模式可作爲你的開啓方法可以返回一個承諾可以解決或由你的對話框拒絕,允許您的控制器根據承諾做出響應。

PLNKR DEMO

<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="[email protected]*" 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>