如何以正确的方式在角度应用程序之间共享控制器之间的数据

时间:2015-12-23 19:51:27

标签: javascript angularjs

嗯,似乎这不是关于这个问题的第一个问题,但是......

我知道我们可以为此使用服务或事件,但互联网上有很多帖子说我们不应该使用很多事件。

我也知道我们可以为此目的创建单独的服务,但在我看来,它也不是那么好。如何观看"数据变化?如何通知smth已被更改?活动?再次?...

还有这些变种的表现怎么样?

那么,实际上什么是真正的好处,也许是角度应用中控制器之间共享数据的最佳方式?而且,做这件事是个好主意吗?这是否意味着我们的应用程序,某些架构或概念问题出了问题?也许这闻到了什么味道?

请指出并给出一个好的建议

提前致谢

更新

这是最常见的问题,因为有时我必须这样做。我想知道这是好事,角度校长是否正确?

3 个答案:

答案 0 :(得分:2)

一种方法是使用范围继承:

angular.module('app', [])
.run(['$rootScope', function($rootScope){
  $rootScope.sharedObj = {search:''};
}])
.controller('navCtr',['$scope',function($scope){
}])
.controller('routeCtr',['$scope',function($scope){
  $scope.$watch("sharedObj.search",function(d){
    $scope.data = d ? 'Searched data is ' + d : '';
  });
}]);
.main div{
  display:inline-block;
  border:1px solid black;
  height:100px;
  vertical-align: top;
}

.navigation{
  width: 20%
}
.navigation input{
  max-width: 70%;
}

.page {
  width: 75%
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" class="main">
  <div ng-controller="navCtr" class="navigation">
    search: <br/>
    <input ng-model="sharedObj.search"/>
  </div>
  <div ng-controller="routeCtr" class="page">
    {{data}}
  </div>
</div>

第二种方式是共享服务:

angular.module('app', [])
.factory('srcObject',[function(){
  return {
    value: ''
  }
}])
.controller('navCtr',['$scope', 'srcObject', function($scope, srcObject){
  $scope.search = srcObject;
}])
.controller('routeCtr',['$scope', 'srcObject', function($scope, srcObject){
  $scope.$watch(function(){return srcObject.value},function(d){
    $scope.data = d ? 'Searched data is ' + d : '';
  });
}]);
.main div{
  display:inline-block;
  border:1px solid black;
  height:100px;
  vertical-align: top;
}

.navigation{
  width: 20%
}
.navigation input{
  max-width: 70%;
}

.page {
  width: 75%
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" class="main">
  <div ng-controller="navCtr" class="navigation">
    search: <br/>
    <input ng-model="search.value"/>
  </div>
  <div ng-controller="routeCtr" class="page">
    {{data}}
  </div>
</div>

答案 1 :(得分:1)

您可以将控制器的上下文直接绑定到服务。这给您带来了以下好处:(1)您不必经常使用$scope; (2)您不必在指令的隔离范围内定义属性; (3)你不必触摸$rootScope; (4)您不必使用$watch$observe,因为需要绑定某事的所有将绑定到您全局的内部API服务。

此模式对于需要共享并了解大量组件之间的大量数据的应用程序非常有用。我在视频播放器中使用了这种模式,其中应用程序的许多远程相关部分必须共享信息并且能够访问彼此的状态:例如,视图中有多少视频播放器,当前时间,持续时间和每个球员的来源等。

这种模式并不特别适合构建真正可重用的组件。如果您选择使用这样的服务,则该指令被硬编码以依赖某个服务。但是,您可以在单个value组件中定义应用程序组件所需的所有属性,这对于定义内部API非常方便。

使用脏检查,我不确定共享一个可能很大的对象是否是一个性能负担。

<强>指令

function() {
    return {
        //if you want the service to hold all the data the directive needs
        //you don't need to define any properties here
        scope: {},
        controller: "SomeCtrl"
    };
}

指令的控制器

angular
    .module("app")
    .controller("SomeCtrl", ["globalService", function(globalService) {
        var vm = this;
        vm.globalService = globalService;
    }]);

<强> HTML

<div>{{vm.globalService.someProperty}}</div>

在一些深层嵌套的模板网址

<!-- another tradeoff is the long naming that can result -->

<div 
    ng-click="panel.state = !panel.state;"
    ng-repeat="panel in vm.globalService.dashboard.sidebar.panelConfig">{{panel.display}}</div>

<强>常数

angular
    .module("app")
    .value("internalAPI", {
        someInitializedThing: true,
        someConfig: [
            { state: true, display: "foobar" },
            { state: false, display: "starts off false" }
        ],
        dashboard: {
            sidebar: {
                panelConfig: [
                    { display: "one panel", state: true },
                    { display: "special panel", state: false }
                ]
            }
        }  
    });

让您的服务注册您已定义的API

angular
    .module("app")
    .service("globalService", ["internalAPI", function(API) {
        var tmp = {};
        for (var p in API)
            tmp[p] = API[p];
        return tmp;
    }])

    //now someplace else, globalService.someNavBar = true

答案 2 :(得分:0)

在此处查看我的帖子,了解如何使用服务在控制器之间共享数据:http://erikaugust.com/thoughts/angularjs-use-the-service-not-the-controller/?ws=so

在博客文章的底部有一个JSFiddle示例链接,可以提供帮助。