是否可以在 AngularJS 中混合注入的依赖项和自定义参数?
Is it possible to mix injected dependencies with custom arguments in AngularJS?
我正在使用 UI Bootstrap 的 $uibModal
创建模态。我也在使用 UI Router 0.2.15,所以我想要的是在新模式中打开的状态。
这是我的配置函数中的内容:
$stateProvider
.state("mystate.substate1", {
url: '...',
template: '<div ui-view></div>',
onEnter: showFirstCustomModal
})
.state("mystate.substate2", {
url: '...',
onEnter: showSecondCustomModal
});
// End of calling code
function showFirstCustomModal($uibModal) {
var options = {
backdrop: 'static',
templateUrl: '...',
controller: 'Controller1',
controllerAs: 'controller'
};
$uibModal.open(options);
}
function showSecondCustomModal($uibModal) {
var options = {
backdrop: 'static',
templateUrl: '...',
controller: 'Controller2',
};
$uibModal.open(options);
}
以上两种模态方式非常相似。我想用通用方法替换它们:
$stateProvider
.state("mystate.substate1", {
url: '...',
onEnter: showGenericModal('some_template','SomeController1', 'alias1')
})
.state("mystate.substate2", {
url: '...',
onEnter: showGenericModal('some_other_template', 'SomeController2')
});
// End of calling code
function showGenericModal(templateUrl, controller, controllerAlias, $uibModal) {
var options = {
backdrop: 'static',
templateUrl: templateUrl,
controller: controller
};
if(!!controllerAlias) {
options.controllerAs: controllerAlias;
}
$uibModal.open(options);
}
我把 $uibModal
作为最后一个参数,以避免它被重新分配。但我无法让它发挥作用。我得到的错误是
Cannot read property 'open' of undefined
此外,我一直在阅读 this 并且我知道您必须使用 $injector 才能注入您的服务。但我认为 UI-Bootstrap.
已经处理好了
因为 $stateProvider
是在 config
块中定义的,所以 $uibModal
不能作为引用从那里传递。
无法在 Angular DI 中混合依赖项和普通参数。对于 onEnter
它应该是一个接受依赖项列表的函数。
上面的代码转换为:
onEnter: showGenericModal('some_other_template', 'SomeController2')
...
function showGenericModal(templateUrl, controller, controllerAlias) {
return ['$uibModal', function ($uibModal) {
...
$uibModal.open(options);
}];
}
或者更好的方法:
onEnter: function (genericModal) {
genericModal.show('some_other_template', 'SomeController2');
}
...
app.service('genericModal', function ($uibModal) {
this.show = function (templateUrl, controller, controllerAlias) {
...
$uibModal.open(options);
}
});
@estus回答正确,不知道怎么没看到状态:"For onEnter it should be a function that accepts the list of dependencies.".
不过,我在这里让我的回答提供另一个角度。您可以定义一个服务来正确地包装和组织您的代码,以便在 onEnter
状态事件上调用自定义模式:
angular.module('app').service('AppModals', AppModals);
// or use /** @ngInject */ aswell
AppModals.$inject = ['$uibModal'];
function AppModals($uibModal) {
this.open = function _generateModal(options) {
var defaultOptions = {
backdrop: 'static'
// Any other default option
};
return $uibModal.open(angular.extend({}, defaultOptions, options);
};
}
关于状态定义:
$stateProvider
.state('app.state', {
url: '/state-modal',
template: '<ui-view></ui-view>',
controller: 'DummyCtrl',
controllerAs: 'dummy',
onEnter: appState_onEnter
});
// or use /** @ngInject */ aswell
appState_onEnter.$inject = ['$uibModal'];
function appState_onEnter(AppModals) {
AppModals.open({
templateUrl: 'modals/state-modal.html',
controller: 'DummyCtrl',
controllerAs: 'dummy'
});
}
我正在使用 UI Bootstrap 的 $uibModal
创建模态。我也在使用 UI Router 0.2.15,所以我想要的是在新模式中打开的状态。
这是我的配置函数中的内容:
$stateProvider
.state("mystate.substate1", {
url: '...',
template: '<div ui-view></div>',
onEnter: showFirstCustomModal
})
.state("mystate.substate2", {
url: '...',
onEnter: showSecondCustomModal
});
// End of calling code
function showFirstCustomModal($uibModal) {
var options = {
backdrop: 'static',
templateUrl: '...',
controller: 'Controller1',
controllerAs: 'controller'
};
$uibModal.open(options);
}
function showSecondCustomModal($uibModal) {
var options = {
backdrop: 'static',
templateUrl: '...',
controller: 'Controller2',
};
$uibModal.open(options);
}
以上两种模态方式非常相似。我想用通用方法替换它们:
$stateProvider
.state("mystate.substate1", {
url: '...',
onEnter: showGenericModal('some_template','SomeController1', 'alias1')
})
.state("mystate.substate2", {
url: '...',
onEnter: showGenericModal('some_other_template', 'SomeController2')
});
// End of calling code
function showGenericModal(templateUrl, controller, controllerAlias, $uibModal) {
var options = {
backdrop: 'static',
templateUrl: templateUrl,
controller: controller
};
if(!!controllerAlias) {
options.controllerAs: controllerAlias;
}
$uibModal.open(options);
}
我把 $uibModal
作为最后一个参数,以避免它被重新分配。但我无法让它发挥作用。我得到的错误是
Cannot read property 'open' of undefined
此外,我一直在阅读 this 并且我知道您必须使用 $injector 才能注入您的服务。但我认为 UI-Bootstrap.
已经处理好了因为 $stateProvider
是在 config
块中定义的,所以 $uibModal
不能作为引用从那里传递。
无法在 Angular DI 中混合依赖项和普通参数。对于 onEnter
它应该是一个接受依赖项列表的函数。
上面的代码转换为:
onEnter: showGenericModal('some_other_template', 'SomeController2')
...
function showGenericModal(templateUrl, controller, controllerAlias) {
return ['$uibModal', function ($uibModal) {
...
$uibModal.open(options);
}];
}
或者更好的方法:
onEnter: function (genericModal) {
genericModal.show('some_other_template', 'SomeController2');
}
...
app.service('genericModal', function ($uibModal) {
this.show = function (templateUrl, controller, controllerAlias) {
...
$uibModal.open(options);
}
});
@estus回答正确,不知道怎么没看到状态:"For onEnter it should be a function that accepts the list of dependencies.".
不过,我在这里让我的回答提供另一个角度。您可以定义一个服务来正确地包装和组织您的代码,以便在 onEnter
状态事件上调用自定义模式:
angular.module('app').service('AppModals', AppModals);
// or use /** @ngInject */ aswell
AppModals.$inject = ['$uibModal'];
function AppModals($uibModal) {
this.open = function _generateModal(options) {
var defaultOptions = {
backdrop: 'static'
// Any other default option
};
return $uibModal.open(angular.extend({}, defaultOptions, options);
};
}
关于状态定义:
$stateProvider
.state('app.state', {
url: '/state-modal',
template: '<ui-view></ui-view>',
controller: 'DummyCtrl',
controllerAs: 'dummy',
onEnter: appState_onEnter
});
// or use /** @ngInject */ aswell
appState_onEnter.$inject = ['$uibModal'];
function appState_onEnter(AppModals) {
AppModals.open({
templateUrl: 'modals/state-modal.html',
controller: 'DummyCtrl',
controllerAs: 'dummy'
});
}