有没有办法从Angular UI嵌套命名视图访问父作用域?

时间:2014-05-28 12:38:02

标签: javascript angularjs angular-ui angular-ui-router

我的应用程序中有几个包含嵌套视图的屏幕。我发现制作模态对话框和面板可以更容易地滑入和滑出实际的嵌套状态与实际的URL,而不是嵌入在html中的一些任意javascript魔法。我发现这种方法有利于重用并创建需要对话框和面板的新页面。它简化了一切。

例如,以下是定义为Angular UI状态时模态和右面板子状态的样子:

    .state('courses.detail.courseVersion.page', {
        url: '/sections/:sectionId/pages/:pageId',
        templateUrl: 'app/courses/courses.detail.courseVersion.page.html',
        resolve: {
            page: function(Model, $stateParams) {
                {not relevant}
            }
        },
        controller: 'PageDetailController'
    })
    .state('courses.detail.courseVersion.page.edit', {
        url: '/edit',
        views: {
            'rightPanel@': {
                templateUrl: 'app/courses/courses.detail.courseVersion.page.edit.html',
                resolve: {
                    {not relevant}
                },
                controller: 'PageFormController'
            }
        }
    })
    .state('courses.detail.courseVersion.page.delete', {
        url: '/delete',
        views: {
            'modal@': {
                templateUrl: 'app/courses/courses.detail.courseVersion.deletePage.html',
                resolve: {
                    {not relevant}
                },
                controller: 'DeletePageController'
            }
        }
    })

DeletePageControllerPageFormController中,我要做的是访问PageDetailController中的范围。例如,如果编辑了Page的标题,我想用该信息更新父作用域,而不是完全重新加载页面(这就是我目前正在做的事情,但是这使得使用ajax失败了。)< / p>

我的第一直觉是查看$scope.$parent的值,但实际上它是空的。这与使用没有命名视图的常规嵌套状态时不同。

如何在不使用根作用域或自定义服务的情况下可靠地访问父作用域来解决此问题?我只想调用父作用域上的一个函数来更新值 - 这将很好地解决我的问题,但如果不使用根作用域,它看起来不可能。

2 个答案:

答案 0 :(得分:1)

尽管Mathew Berg已经回答你应该使用服务在控制器之间共享数据,但你可以共享/继承范围变量(尽管可能不鼓励)。

<div ng-controller="BaseCtrl">
<div ng-controller="InnerCtrl">
...
</div>
</div>

function BaseCtrl($scope) {
  $scope.shared = {
    fun : true
  };
}

function InnerCtrl($scope) {
  console.log('fun', $scope.shared.fun);
  $scope.shared.lol = 'always';
}

我使用的是一个简单(工作)语法的示例。只需记住在共享对象上放置属性 - 不要像这样覆盖它:

function InnerCtrl($scope) {
  $scope.shared = {
    lol: 'always'
  };
}

这将打破BaseCtrl持有的对象的链接。有时你需要应用几个属性,手动输入/复制它们可能很难。你可以这样做:

function InnerCtrl($scope) {
  var model = {
    lol : 'always',
    shout: function () { console.log('yay!'); }
  };

  angular.copy($scope.shared, model); // shared now also holds lol and shout.
}

答案 1 :(得分:0)

您应该使用一个可以访问的所有服务共享的服务。