使用给定的 parent 绑定控制器
Bind a controller with a given parent
使用 Angular Bootstrap 和 $modal 服务,我使用以下模板创建了一个弹出窗口:
<div class="dialog modal-header" ng-show="header.length > 0">
<h3 compile="header"></h3>
</div>
<div class="dialog modal-body">
<div compile="bodyTemplate"></div>
</div>
<div class="dialog modal-footer">
<button ng-repeat="button in buttons"
ng-show="$parent.$eval(button.showExpression)"
ng-class="button.class"
ng-click="onButtonClick(button)">
<div compile="button.template"/>
</button>
</div>
我构建了一个弹出服务来帮助设置范围的默认值,以及从 templateUrl 加载 bodyTemplate。
// snippit of my popup service
function show(modalOptions, scope) {
// ....
// load template from modalOptions.bodyTemplateUrl
// ....
var extendedModalOptions = {};
angular.extend(extendedModalOptions, defaultModelOptions, modalOptions);
extendedModalOptions.controller = function ($scope, $modalInstance) {
angular.extend($scope, scope);
// ....
// add to $scope additional properties from the extendedModalOptions
// such as the buttons array and loaded bodyTemplate
// ....
}
$modal.open(extendedModalOptions);
}
我想要的是注入一个用于bodyTemplate的控制器,像这样:
<div class="dialog modal-header" ng-show="header.length > 0">
<h3 compile="header"></h3>
</div>
<!-- Note the addition of ng-controller here -->
<div class="dialog modal-body" ng-controller="bodyController">
<div compile="bodyTemplate"></div>
</div>
<div class="dialog modal-footer">
<button ng-repeat="button in buttons"
ng-show="$parent.$eval(button.showExpression)"
ng-class="button.class"
ng-click="onButtonClick(button)">
<div compile="button.template"/>
</button>
</div>
这可以工作,但是,bodyController 作用域的 $parent 现在是给 $modal 控制器的作用域。我想使用不同的 parent.
我希望能够像这样使用我的弹出服务:
// from inside CustomerController
popup.show({
header: 'Test Popup',
parentScope: $scope, // the current scope of CustomerController
bodyTemplateUrl: 'testPopupTemplate.html',
bodyController: 'TestPopupController as testPopupVM'
});
这是我有点迷路的地方。我认为我的弹出服务可以像这样创建控制器:
$scope.bodyController = $controller(extendedModalOptions.bodyController, {
$scope: extendedModalOptions.parentScope
});
我不是 100% 确定,但我认为这让我的控制器具有正确的 parent。然而,问题是返回值是新作用域object,而不是构造函数。
根据 ng-controller 上的 angular 文档,它只能绑定到构造函数。
如何在使用提供的 parent 范围时将主体控制器添加到弹出模板?
您正在尝试创建自己的 $scope
层次结构,而 Angular 提供的层次结构就可以了。
默认情况下,使用 $modal
服务打开的模式从 $rootScope
获取新的子作用域。您可以通过显式设置基本模态范围来更改此设置,即
$modal({
scope: yourBaseScope
// other modal options
})
Modal 将在创建时调用 yourBaseScope.$new()
并使用它。因此,它将可以访问您在 yourBaseScope
.
中定义的所有变量和函数
阅读更多关于模态范围的信息in docs。
fracz 的答案是更好的选择,但我想提供一个替代 hack。
由于ng-controller只能绑定一个controller function,所以我在popup service里面建了一个:
$scope.bodyCtrl = function($scope) {
// HACK: replace the parent with the one from extendedModalOptions
$scope.$parent = extendedModalOptions.parentScope;
return $controller(extendedModalOptions.bodyController, {
$scope: $scope
});
};
// annotate the controller function so minification does't break injection
$scope.bodyCtrl['$inject'] = ['$scope'];
手动替换作用域上的 $parent 有代码味。我没有意识到你可以传递 $rootScope 替代 $modal.
使用 Angular Bootstrap 和 $modal 服务,我使用以下模板创建了一个弹出窗口:
<div class="dialog modal-header" ng-show="header.length > 0">
<h3 compile="header"></h3>
</div>
<div class="dialog modal-body">
<div compile="bodyTemplate"></div>
</div>
<div class="dialog modal-footer">
<button ng-repeat="button in buttons"
ng-show="$parent.$eval(button.showExpression)"
ng-class="button.class"
ng-click="onButtonClick(button)">
<div compile="button.template"/>
</button>
</div>
我构建了一个弹出服务来帮助设置范围的默认值,以及从 templateUrl 加载 bodyTemplate。
// snippit of my popup service
function show(modalOptions, scope) {
// ....
// load template from modalOptions.bodyTemplateUrl
// ....
var extendedModalOptions = {};
angular.extend(extendedModalOptions, defaultModelOptions, modalOptions);
extendedModalOptions.controller = function ($scope, $modalInstance) {
angular.extend($scope, scope);
// ....
// add to $scope additional properties from the extendedModalOptions
// such as the buttons array and loaded bodyTemplate
// ....
}
$modal.open(extendedModalOptions);
}
我想要的是注入一个用于bodyTemplate的控制器,像这样:
<div class="dialog modal-header" ng-show="header.length > 0">
<h3 compile="header"></h3>
</div>
<!-- Note the addition of ng-controller here -->
<div class="dialog modal-body" ng-controller="bodyController">
<div compile="bodyTemplate"></div>
</div>
<div class="dialog modal-footer">
<button ng-repeat="button in buttons"
ng-show="$parent.$eval(button.showExpression)"
ng-class="button.class"
ng-click="onButtonClick(button)">
<div compile="button.template"/>
</button>
</div>
这可以工作,但是,bodyController 作用域的 $parent 现在是给 $modal 控制器的作用域。我想使用不同的 parent.
我希望能够像这样使用我的弹出服务:
// from inside CustomerController
popup.show({
header: 'Test Popup',
parentScope: $scope, // the current scope of CustomerController
bodyTemplateUrl: 'testPopupTemplate.html',
bodyController: 'TestPopupController as testPopupVM'
});
这是我有点迷路的地方。我认为我的弹出服务可以像这样创建控制器:
$scope.bodyController = $controller(extendedModalOptions.bodyController, {
$scope: extendedModalOptions.parentScope
});
我不是 100% 确定,但我认为这让我的控制器具有正确的 parent。然而,问题是返回值是新作用域object,而不是构造函数。
根据 ng-controller 上的 angular 文档,它只能绑定到构造函数。
如何在使用提供的 parent 范围时将主体控制器添加到弹出模板?
您正在尝试创建自己的 $scope
层次结构,而 Angular 提供的层次结构就可以了。
默认情况下,使用 $modal
服务打开的模式从 $rootScope
获取新的子作用域。您可以通过显式设置基本模态范围来更改此设置,即
$modal({
scope: yourBaseScope
// other modal options
})
Modal 将在创建时调用 yourBaseScope.$new()
并使用它。因此,它将可以访问您在 yourBaseScope
.
阅读更多关于模态范围的信息in docs。
fracz 的答案是更好的选择,但我想提供一个替代 hack。
由于ng-controller只能绑定一个controller function,所以我在popup service里面建了一个:
$scope.bodyCtrl = function($scope) {
// HACK: replace the parent with the one from extendedModalOptions
$scope.$parent = extendedModalOptions.parentScope;
return $controller(extendedModalOptions.bodyController, {
$scope: $scope
});
};
// annotate the controller function so minification does't break injection
$scope.bodyCtrl['$inject'] = ['$scope'];
手动替换作用域上的 $parent 有代码味。我没有意识到你可以传递 $rootScope 替代 $modal.