打开modal并传递父作用域参数给它

ui-router: open modal and pass parent scope parameters to it

本文关键字:作用域 参数 modal 打开      更新时间:2023-09-26

我正在使用这个常见问题解答条目在某个状态的子状态下打开一个模态对话框:https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-open-a-dialogmodal-at-a-certain-state

我的代码如下。当我打开一个模态对话框时,我需要访问父状态作用域的属性。这可能吗?

plnkr: http://plnkr.co/edit/knY87n

         .state('edit', {
             url: '/{id:[0-9a-f]+}',
             views: {
                 '@': {
                     templateUrl: 'views/edit.html',
                     controller: 'editContr'
                 }
             }
         })
         .state('edit.item', {
             url: "/item/new",
             onEnter: function($stateParams, $state, $modal) {
                 $modal.open({
                     controller: 'itemEditContr',
                     templateUrl: 'views/edit-item.html',
                 }).result.then(function (item) {
                     //
                     // here I need to insert item into the items
                     // seen by my parent state. how?
                     //
                     $state.go('^');
                 }, function () {
                     $state.go('^');
                 });
             }
         });

function editContr($scope) {
    $scope.items = [{name: 'a'}, {name: 'b'}, {name: 'c'}];
}
function itemEditContr($scope, $modalInstance) {
     $scope.submit = function () {
         $modalInstance.close($scope.item);
     };
     $scope.cancel = function () {
         $modalInstance.dismiss('cancel');
     };
     $scope.item = {name: 'test'};
}

您打算更新父类设置的参数吗?您应该能够使用

获取父状态。
$state.$current.parent

例如,父状态的名称将是$state。

编辑:更新,因为OP想要访问作用域而不是父状态。

你可以从子进程发出一个事件,然后在父进程中捕获它。

未测试的代码:父:

$scope.$on('ADD_ITEM', function(evt, msg) {
     $scope.items.add(msg);
}

子状态:

$scope.$emit('ADD_ITEM', item);

长话短说,是的。阅读angularjs开发者指南中的作用域,这实际上是其中一个更有帮助且文档详细的部分:http://docs.angularjs.org/guide/scope

除此之外,angular中的作用域与任何javascript对象的作用域没有什么不同。

你总有一两件事做得不对。首先,在onEnter函数中传递item不会有帮助,除非你从url中抓取一些东西作为标识符,或者重新分配一些你可以注入状态控制器的数据。您正在尝试执行后者,但是您没有解决任何问题,因此您在项目上获得undefined

你可以使用的一个技巧是在你的父元素中设置一个真值,并访问它。

 //in parent ctrl
 $scope.newItem = function(itemname){
     return {name:itemname}
 }
 $scope.save = function(item){
    $scope.items.push(item);
}

然后当你打开你的模态调用$scope.getItem()在控制器而不是直接注入项目到控制器

function itemEditContr($scope, $modalInstance) {
     $scope.submit = function () {
         $modalInstance.close();
     };
     $scope.cancel = function () {
         $modalInstance.dismiss('cancel');
     };
     $scope.item = $scope.newItem('test') //this will look for newItem funciton in the local scope, fail to find it, and walk up the heirarchy until it has found newItem() in the parent
    //now a save function, also defined on the parent scope
    $scope.save($scope.item);

}

访问父作用域没有什么特别的,只是确保获得一个值,而不是覆盖它。所以你可以访问$scope.items从子控制器通过分配它到一个变量,或者你可以推它的新值,但从来没有设置它,或者你将创建一个新的本地项目对象的子范围而不是。

我对此也很纠结,并找到了另一种解决方案。代替使用onEnter函数,你可以使用一个带有非常简单视图的控制器,该视图调用一个函数来打开模态。我用了

config(['$stateProvider', function($stateProvider) {
            // Now set up the states
            $stateProvider
                    .state('exmple.modal', {
                        url: "/example/modal/",
                        controller: "ExampleController",
                        template: '<div ng-init="openModal()"></div>'
                    });
        }]);        

在示例控制器中,您可以放置openModal()函数来打开有作用域的模态