繁体   English   中英

如何以正确的方式在Angle App中的控制器之间共享数据

[英]How to share data between controllers in angular app in the right way

好吧,这似乎不是关于此主题的第一个问题,但是...

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

我也知道我们可以为此目的创建单独的服务,但是我认为它也不是很好。 如何“观察”数据变化? 如何通知水银已更改? 活动? 再次?...

而且,每个变体的性能如何?

那么,在角度应用中,在控制器之间共享数据的真正的好处,也许是最好的方法是什么? 此外,做这件事是个好主意吗? 这是否意味着我们的应用程序有问题,体系结构或概念上的问题? 也许这闻起来很臭?

请指点我并给个很好的建议

提前致谢

更新

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

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

 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)您不必大量使用$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

在这里查看有关使用服务在控制器之间共享数据的文章: http : //erikaugust.com/thoughts/angularjs-use-the-service-not-the-controller/?ws=so

博客文章底部有一个指向JSFiddle示例的链接,该示例会有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM