我看到使用angular-ui / bootstrap的$modal
的例子看起来总是这样:
$modal.open({
templateUrl: 'modaltemplate.html',
controller: function($scope) {
...
}
});
如果我想使用指令,该怎么办?像这样:
$modal.open({
template: '<my-modal-directive></my-modal-directive>'
// no "controller" property; use directive's controller
});
my-modal-directive
的标记呈现正常,我已将controller
属性移动到my-modal-directive
定义对象中,但现在从my-modal-directive
获取此错误:< / p>
Error: [$injector:unpr] Unknown provider: $modalInstanceProvider <- $modalInstance
有人能指出一个例子$modal
使用指令定义controller
吗?
例如,这有效,我用指令替换了templateUrl
:
http://plnkr.co/edit/YrGaF83GH6bzZPRR55GK?p=preview
但是当我将控制器从$modal.open()
移动到指令中时,就会发生错误:
http://plnkr.co/edit/aLBT239EpL004DRh4jll?p=preview
答案 0 :(得分:6)
问题是$modalInstance
只能注入您提供给$modal.open
的控制器中。
查看来源here:
$modal.open = function (modalOptions) {
...
var modalInstance = {
...
};
...
if (modalOptions.controller) {
...
ctrlLocals.$modalInstance = modalInstance;
...
ctrlInstance = $controller(modalOptions.controller, ctrlLocals);
...
}
...
}
实质上,当您尝试将$modalInstance
作为依赖项添加到控制器时,AngularJS会查找名为$modalInstanceProvider
的已注册全局提供程序。现在问题是,如果您理解上面的代码,$modalInstance
不是全球注册的提供商。只有&#34;存在&#34;作为传递给$modal.open
的控制器的依赖项。
如果您阅读了其余代码,您会注意到$modal.open
返回modalInstance
,也许您可以使用该代码。
像this:
function SomeController($modal) {
$scope.modal = {
instance: null
};
$scope.modal.instance = $modal.open({
template: '<my-modal-directive modal="modal"></my-modal-directive>',
scope: $scope
});
}
function MyModalDirective() {
scope: {
modal: '='
},
link: function($scope) {
// here you can access $scope.modal.instance
}
}
答案 1 :(得分:5)
您遇到的问题是您正在尝试注入无法注入的值。只能注入注射器注册的值。
您的代码逻辑也有缺陷,您在主控制器中创建模态但尝试在指令中关闭它。理想情况下,模态应该由指令触发(通过它的链接功能),然后你可以从那里确定/取消它。
有关一种可能的方法,请参阅我的http://plnkr.co/edit/3p1rXAymd7BilyklgxKy?p=preview,我保留了关闭的代码并取消了主控制器中的模式。
angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
angular.module('ui.bootstrap.demo').directive('myModal', function() {
return {
restrict: 'E',
templateUrl: 'myModalContent.html',
controller: function ($scope) {
$scope.selected = {
item: $scope.items[0]
};
}
};
});
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function (size) {
var modalInstance;
var modalScope = $scope.$new();
modalScope.ok = function () {
modalInstance.close(modalScope.selected);
};
modalScope.cancel = function () {
modalInstance.dismiss('cancel');
};
modalInstance = $modal.open({
template: '<my-modal></my-modal>',
size: size,
scope: modalScope
}
);
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
});
答案 2 :(得分:3)
我创建了一个指令来轻松创建模态。模态内容基于模板视图。
angular.module('your_app').directive('modalViewUrl', function ($modal) {
return {
restrict: 'A', // A: attribute
scope: { // isolate scope
'modalViewUrl': '@', // modal view url to render the modal content
'modalController': '@' // modal view controller (optional)
},
link: function($scope, element, attrs){
element.bind('click', function(){
var template =
'<div class="modal-body">' +
'<button ng-click="$close()" type="button" class="close" aria-label="Close">' +
'<span aria-hidden="true">×</span>' +
'</button>' +
'<div ng-include="\'' + $scope.modalViewUrl + '\'"></div>' +
'</div>';
// see modal reference from ui bootstrap at <http://angular-ui.github.io>
var modalInstance = $modal.open({
animation: true,
template: template,
controller: $scope.modalController,
});
});
}
};
});
如何使用它的示例:
<强>的index.html 强>
<a modal-view-url="hello.html" modal-controller="HelloCtrl" href="#">
Click here to open the modal
</a>
<强> hello.html的强>
<h1> Hello World {{name}} </h1>
<强> HelloCtrl.js 强>
angular.module('yourApp').controller('HelloCtrl',
function ($scope, $modalInstance) {
// $modalInstance: same from from ui bootstrap
$scope.name = "Xico";
});
模态视图可以有自己的控制器。例如:
hello.html(已修改)
<h1 ng-controller="Hello2Ctrl"> {{msg}} {{name}} </h1>
<强> Hello2Ctrl.js 强>
angular.module('yourApp').controller('Hello2Ctrl',
function ($scope) {
$scope.msg = "Hello Worldsszz";
$scope.name = "Zefa";
});
观察模态输出为“Hello Worldsszz Xico”,因为模态控制器(HelloCtrl)将在视图控制器(Hello2)之后呈现。
答案 3 :(得分:2)
它的回复更晚,但有人可能会发现它很有用。
我已经加强了Fernando Felix的答案,并制定了我自己非常灵活的指令,与控制器进行通信,我认为这可能是解决这个问题的方法。
<强>指令强>
var modalUrl = function ($modal) {
return {
restrict: 'A', // A: attribute
scope: { // isolate scope
'modalUrl': '@', // modal view url to render the modal content
'modalController': '@', // modal view controller (optional)
'value': "="
},
link: function(scope, element, attrs){
console.log('modalUrl link');
var modalInstance;
var template = [
'<div class="modal-body">',
'<button ng-click="$close()" type="button" class="close" aria-label="Close">',
'<span aria-hidden="true">×</span>',
'</button>',
'<div ng-include="\'' + scope.modalUrl + '\'"></div>',
'</div>'
].join('');
element.bind('click', function(){
// see modal reference from ui bootstrap at <http://angular-ui.github.io>
modalInstance = $modal.open({
size: attrs.size,
animation: true,
template: template,
resolve: {
params: function () {
console.log('value passed to modal:');
console.log(scope.value);
return scope.value;
}
},
controller: scope.modalController
});
modalInstance.result.then(
function (returnValue) {
// alert('value: '+returnValue);
console.log('modal returnValue:');
console.log(returnValue);
scope.value = returnValue;
}, function () {
console.log('Modal dismissed at: ' + new Date());
}
);
});
}
};
}
modalUrl.$inject = ['$modal'];
angular.module('app').directive('modalUrl', modalUrl);
<强>控制器强>
var HelloCtrl = function ($scope, $modalInstance, modalVal) {
// $modalInstance: same from from ui bootstrap
console.log('Hello init!');
// modalVal is the init modal value passed via directive
console.log(modalVal);
// your code
$scope.name = modalVal;
$scope.ok = function() {
$modalInstance.close(this.name); // returnValue
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
}
HelloCtrl.$inject = ['$scope', '$modalInstance','params'];
angular.module('app').controller('HelloCtrl',HelloCtrl);
内嵌模板
<script type="text/ng-template" id="hello.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<input type="text" ng-model="name" />
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn" ng-click="cancel()">Cancel</button>
</div>
</script>
每个弹出窗口类型有一个控制器和模板,然后您可以多次调用它:
<a modal-url="hello.html" modal-controller="HelloCtrl" value="yourVal" ng-init="yourVal='test'" href="#">Click here to open the modal</a>
您可以使用任何内容初始化值 - 即。对象,数组等。
或外部模板
几乎相同,只是网址更改和模板文件用于模板。
<a modal-url="/modal/test1.html" modal-controller="HelloCtrl" value="yourVal" ng-init="yourVal='test'" href="#">Click here to open the modal</a>
test1.html
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<input type="text" ng-model="name" />
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn" ng-click="cancel()">Cancel</button>
</div>
模态大小等
只需添加参数大小=&#34; sm | lg&#34;对于模态链接/按钮即。 单击此处打开模态 对于标准尺寸,请跳过参数。 您可以使用链接功能attrs自行增强它。
答案 4 :(得分:1)
我是神田后期重播,最简单的方法是使用
$scope.$parent.$close(result);
$scope.$parent.$dismiss(reason);
这适用于您的指令控制器。