ui-router:打开模态并将父作用域参数传递给它

时间:2014-03-21 03:50:38

标签: javascript angularjs angular-ui-router

我正在使用此FAQ条目在某个州的子状态下打开模式对话框: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'};
}

3 个答案:

答案 0 :(得分:4)

您是否计划更新父级设置的参数?您应该能够使用

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

例如父状态的名称将是$ state。$ current.parent.name

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

您可以从孩子发出一个事件,然后在父母中捕获它。

未经测试的代码: 在父母:

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

在孩子的状态:

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

答案 1 :(得分:1)

长话短说,是的。阅读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,或者您可以将其推送到新值,但从不设置它,或者您将创建一个新的本地项目对象而是孩子的范围。

答案 2 :(得分:0)

我也在努力解决这个问题,并找到了另一种解决方案。您可以使用具有非常简单视图的控制器来调用函数来打开模态,而不是使用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()函数打开具有范围的模态。