2013-05-03 27 views
8

Tôi muốn quảng cáo mới (hộp thoại) type đến góc cạnh, vì vậy tôi có thể sử dụng nó giống như tôi sử dụng module.directive, module.filter, module.controller đăng ký chỉ thị, bộ lọc và bộ điều khiển.AngularJS - mở rộng mô-đun với các loại riêng/nhà cung cấp

Tôi muốn đăng ký trường hợp của tôi dialog loại theo cách này:

module.dialog('prompt',function(dependencies){ 
    return { 
     templateUrl:'prompt.html', 
     controller:function($scope){}, 
     something:'value' 
    } 
}); 

Tôi cũng muốn để có thể sử dụng hộp thoại đã đăng ký trong các bộ điều khiển (dependency injection)

module.controller('ListCtrl',function($scope,prompt){ 
    $scope.deleteItem = function(item){ 
     prompt('Do you want to delete this item?').then(function(result){ 
      if(result) item.$delete(); 
     }); 
    } 
}); 

này nắm đến các câu hỏi sau:

  1. Làm cách nào để mở rộng mô-đun góc để có module.dialog đăng ký các loại dialog của tôi?

  2. Làm cách nào để đăng ký dialogs đã đăng ký của mình vào số controllers v.v ...?

Btw,

  • tôi biết về angular-uiangular-strap.
  • Tôi không muốn sử dụng dialog làm dịch vụ, nhưng dưới dạng riêng biệt type (giải pháp này đã được triển khai trong angular-ui).
+0

tại sao bạn không chỉ sử dụng chỉ thị? – charlietfl

+0

Có lý do nào bạn muốn làm điều đó trái ngược với giải pháp bootstrap không? – zcaudate

+0

@zcaudate, tôi không thích cách hộp thoại đăng ký bootstrap - bạn xác định hộp thoại của bạn trong bộ điều khiển. Tôi muốn tách các hộp thoại khỏi bộ điều khiển. – g00fy

Trả lời

7

Đây là một câu hỏi khá thú vị. Tôi sẽ thêm tiền tố cho câu trả lời của tôi với một ý kiến: Tôi không nghĩ bạn nên mở rộng angular.module để cung cấp phương thức dialog. Các phương thức này là các lối tắt vào các nhà cung cấp Angular có sẵn và nhóm Angular cũng thêm vào một số thời điểm. Vì bạn có thể truy cập vào chức năng mà bạn đang tìm kiếm mà không cần thêm phương thức dialog, tôi sẽ không. Điều đó nói rằng, đoạn code dưới đây cho bạn thấy một phiên bản rất cơ bản của việc này có thể hoạt động như thế nào (nó không sửa đổi nguyên mẫu mô-đun góc, chỉ là một cá thể duy nhất của mô-đun).

<div ng-app="myApp"> 
    <div ng-controller='MainController'> 
    <div> 
     <button ng-click='askName()'>Ask Name</button> 
     <button ng-click='askNameAgain()'>Ask Name Again</button> 
     <button ng-click='askAge()'>Ask Age</button> 
     <button ng-click='askFood()'>Ask Food</button> 
    </div> 
    <div>{{lastResponse}}</div> 
    </div> 
</div> 
var app = angular.module('myApp', []); 

// Provide some basic injectables for testing 
app.constant('nameString', 'NAME'); 
app.constant('ageString', 'AGE'); 
app.constant('foodString', 'FAVORITE FOOD'); 

// Create the dialog provider 
app.provider('dialog', function($provide, $injector) { 
    var dialogs = {}; 

    this.register = function(name, configFn) { 
    // Create a new service 
    $provide.factory(name, function($window, $q) { 
     dialogs[name] = function() { 
     // Get data based on DI injected version of configFn 
     var data = $injector.invoke(configFn); 
     // faking async here since prompt is really synchronous 
     var deferred = $q.defer(); 
     var response = $window.prompt(data.text); 
     deferred.resolve(response); 
     return deferred.promise; 
     }; 
     return dialogs[name]; 
    }); 
    }; 

    // Injecting the service itself gives you a function that 
    // allows you to access a dialog by name, much like $filter 
    this.$get = function() { 
    return function(name) { 
     return dialogs[name]; 
    }; 
    }; 
}); 

// Providing dialog injectables via app.config 
app.config(function(dialogProvider) { 
    dialogProvider.register('askFood', function(foodString) { 
    return { text: 'What is your ' + foodString + '?' } 
    }); 
}); 

// Alternatively, shortcut to accessing the dialogProvider via app.dialog 
app.dialog = function(name, configFn) { 
    app.config(function(dialogProvider) { 
    dialogProvider.register(name, configFn); 
    }); 
}; 

app.dialog('askName', function(nameString) { 
    return { text: 'What is your ' + nameString + '?' } 
}); 

app.dialog('askAge', function(ageString) { 
    return { text: 'What is your ' + ageString + '?' } 
}); 

app.controller('MainController', 
       function($scope, askName, askAge, askFood, dialog) { 
    var setLastResponse = function(result) { 
    $scope.lastResponse = result; 
    }; 

    $scope.askName = function() { 
    askName().then(setLastResponse); 
    }; 

    $scope.askNameAgain = function() { 
    // get the dialog through the dialog service 
    // much like how $filter works 
    var theDialog = dialog('askName'); 
    theDialog().then(setLastResponse); 
    }; 

    $scope.askAge = function() { 
    askAge().then(setLastResponse); 
    }; 

    $scope.askFood = function() { 
    askFood().then(setLastResponse); 
    }; 
}); 

Dưới đây là một ví dụ làm việc: http://jsfiddle.net/BinaryMuse/zj4Jq/

Bằng cách tận dụng $injector.invoke bên trong chức năng dialogProvider.register của bạn, bạn có thể cung cấp khả năng sử dụng một chìa khóa như controller trong các dữ liệu configFn lợi nhuận của bạn. Kể từ khi directive hoạt động rất nhiều như thế này, bạn có thể đạt được rất nhiều từ việc kiểm tra the AngularJS source.

Các vấn đề liên quan