AngularJS:如何在控制器之间传递变量
AngularJS: How can I pass variables between controllers?
我有两个 Angular 控制器:
function Ctrl1($scope) {
$scope.prop1 = "First";
}
function Ctrl2($scope) {
$scope.prop2 = "Second";
$scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}
我不能在Ctrl2
里面使用Ctrl1
,因为它是未定义的。但是,如果我尝试像这样传递它...
function Ctrl2($scope, Ctrl1) {
$scope.prop2 = "Second";
$scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}
我收到一个错误。有谁知道如何做到这一点?
行为
Ctrl2.prototype = new Ctrl1();
也失败了。
注意:这些控制器不相互嵌套。
在多个控制器之间共享变量的一种方法是创建一个服务并将其注入到要使用它的任何控制器中。
简单服务示例:
angular.module('myApp', [])
.service('sharedProperties', function () {
var property = 'First';
return {
getProperty: function () {
return property;
},
setProperty: function(value) {
property = value;
}
};
});
在控制器中使用服务:
function Ctrl2($scope, sharedProperties) {
$scope.prop2 = "Second";
$scope.both = sharedProperties.getProperty() + $scope.prop2;
}
这在本博客中得到了很好的描述(特别是第 2 课(。
我发现,如果要跨多个控制器绑定到这些属性,则绑定到对象的属性而不是基元类型(布尔值、字符串、数字(以保留绑定引用的效果会更好。
示例:var property = { Property1: 'First' };
而不是var property = 'First';
。
更新:为了(希望(让事情更清楚,这里有一个小提琴,展示了一个例子:
- 绑定到共享值的静态副本(在 myController1 中(
- 绑定到基元(字符串(
- 绑定到对象的属性(保存到范围变量(
- 绑定到在值更新时更新 UI 的共享值(在 myController2 中(
- 绑定到返回基元(字符串(的函数
- 绑定到对象的属性
- 双向绑定到对象的属性
我喜欢用简单的例子来说明简单的事情:)
下面是一个非常简单的Service
示例:
angular.module('toDo',[])
.service('dataService', function() {
// private variable
var _dataObj = {};
// public API
this.dataObj = _dataObj;
})
.controller('One', function($scope, dataService) {
$scope.data = dataService.dataObj;
})
.controller('Two', function($scope, dataService) {
$scope.data = dataService.dataObj;
});
在这里,jsbin
这是一个非常简单的Factory
示例:
angular.module('toDo',[])
.factory('dataService', function() {
// private variable
var _dataObj = {};
// public API
return {
dataObj: _dataObj
};
})
.controller('One', function($scope, dataService) {
$scope.data = dataService.dataObj;
})
.controller('Two', function($scope, dataService) {
$scope.data = dataService.dataObj;
});
在这里,jsbin
如果这太简单了,这里有一个更复杂的例子
另请参阅此处的答案,了解相关的最佳实践评论
这个答案不是针对这个问题的,但我希望阅读这个问题并希望处理工厂等服务的人避免麻烦做这个----
为此,您需要使用服务或工厂。
这些服务是在非嵌套控制器之间共享数据的最佳实践。
关于这个关于数据共享的主题的一个非常好的注释是如何声明对象。我很不幸,因为我在阅读之前就掉进了 AngularJS 陷阱,我非常沮丧。所以让我帮你避免这个麻烦。
我从"ng-book:关于AngularJS的完整书籍"中读到,在控制器中创建的AngularJS ng模型作为裸数据是错误的!
应按如下方式创建$scope元素:
angular.module('myApp', [])
.controller('SomeCtrl', function($scope) {
// best practice, always use a model
$scope.someModel = {
someValue: 'hello computer'
});
而不是这样:
angular.module('myApp', [])
.controller('SomeCtrl', function($scope) {
// anti-pattern, bare value
$scope.someBareValue = 'hello computer';
};
});
这是因为建议(最佳实践(让 DOM(html 文档(包含调用
<div ng-model="someModel.someValue"></div> //NOTICE THE DOT.
如果您希望子控制器能够从父控制器更改对象,这对于嵌套控制器非常有用。
但在您的情况下,您不需要嵌套作用域,但有一个类似的方面将对象从服务获取到控制器。
假设您有您的服务"工厂",并且在返回空间中有一个包含对象 B 的对象 A,该对象 B 包含对象 C。
如果从控制器中你想将objectC放入你的范围,那么说是错误的:
$scope.neededObjectInController = Factory.objectA.objectB.objectC;
那行不通...而是只使用一个点。
$scope.neededObjectInController = Factory.ObjectA;
然后,在 DOM 中,您可以从对象 A 调用对象 C。这是与工厂相关的最佳实践,最重要的是,它将有助于避免意外和不可捕获的错误。
无需创建服务的解决方案,使用 $rootScope:
若要跨应用控制器共享属性,可以使用 Angular $rootScope。这是共享数据的另一种选择,以便人们知道它。
跨控制器共享某些功能的首选方法是服务,用于读取或更改可用于$rootscope的全局属性。
var app = angular.module('mymodule',[]);
app.controller('Ctrl1', ['$scope','$rootScope',
function($scope, $rootScope) {
$rootScope.showBanner = true;
}]);
app.controller('Ctrl2', ['$scope','$rootScope',
function($scope, $rootScope) {
$rootScope.showBanner = false;
}]);
在模板中使用$rootScope(使用 $root 访问属性(:
<div ng-controller="Ctrl1">
<div class="banner" ng-show="$root.showBanner"> </div>
</div>
上面的示例就像一个魅力。我只是做了一个修改,以防我需要管理多个值。我希望这有帮助!
app.service('sharedProperties', function () {
var hashtable = {};
return {
setValue: function (key, value) {
hashtable[key] = value;
},
getValue: function (key) {
return hashtable[key];
}
}
});
我倾向于使用值,很高兴有人讨论为什么这是一个坏主意。
var myApp = angular.module('myApp', []);
myApp.value('sharedProperties', {}); //set to empty object -
然后根据服务注入值。
在 ctrl1 中设置:
myApp.controller('ctrl1', function DemoController(sharedProperties) {
sharedProperties.carModel = "Galaxy";
sharedProperties.carMake = "Ford";
});
和从 Ctrl2 访问:
myApp.controller('ctrl2', function DemoController(sharedProperties) {
this.car = sharedProperties.carModel + sharedProperties.carMake;
});
演示如何在同级控制器之间传递变量,并在值更改时执行操作。
用例示例:侧边栏中有一个过滤器,用于更改另一个视图的内容。
angular.module('myApp', [])
.factory('MyService', function() {
// private
var value = 0;
// public
return {
getValue: function() {
return value;
},
setValue: function(val) {
value = val;
}
};
})
.controller('Ctrl1', function($scope, $rootScope, MyService) {
$scope.update = function() {
MyService.setValue($scope.value);
$rootScope.$broadcast('increment-value-event');
};
})
.controller('Ctrl2', function($scope, MyService) {
$scope.value = MyService.getValue();
$scope.$on('increment-value-event', function() {
$scope.value = MyService.getValue();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<h3>Controller 1 Scope</h3>
<div ng-controller="Ctrl1">
<input type="text" ng-model="value"/>
<button ng-click="update()">Update</button>
</div>
<hr>
<h3>Controller 2 Scope</h3>
<div ng-controller="Ctrl2">
Value: {{ value }}
</div>
</div>
指出在控制器甚至指令之间共享数据的推荐方法是使用已经指出的服务(工厂(,但我也想提供一个工作的实际示例来说明应该如何做到这一点。
这是工作弹道机:http://plnkr.co/edit/Q1VdKJP2tpvqqJL1LF6m?p=info
首先,创建将具有共享数据的服务:
app.factory('SharedService', function() {
return {
sharedObject: {
value: '',
value2: ''
}
};
});
然后,只需将其注入控制器并获取示波器上的共享数据:
app.controller('FirstCtrl', function($scope, SharedService) {
$scope.model = SharedService.sharedObject;
});
app.controller('SecondCtrl', function($scope, SharedService) {
$scope.model = SharedService.sharedObject;
});
app.controller('MainCtrl', function($scope, SharedService) {
$scope.model = SharedService.sharedObject;
});
您也可以为您的指令执行此操作,它的工作方式相同:
app.directive('myDirective',['SharedService', function(SharedService){
return{
restrict: 'E',
link: function(scope){
scope.model = SharedService.sharedObject;
},
template: '<div><input type="text" ng-model="model.value"/></div>'
}
}]);
希望这个实用而干净的答案对某人有所帮助。
你可以用服务或工厂来做到这一点。除了一些核心差异之外,它们本质上是相同的。我发现 thinkster.io 这个解释是最容易理解的。简单,切中要害且有效。
您不能也使属性成为范围父级的一部分吗?
$scope.$parent.property = somevalue;
我不是说这是对的,但它有效。
啊,有一点这个新东西作为另一种选择。它是本地存储,并且在角度工作的地方工作。别客气。(但真的,谢谢那个人(
https://github.com/gsklee/ngStorage
定义默认值:
$scope.$storage = $localStorage.$default({
prop1: 'First',
prop2: 'Second'
});
访问值:
$scope.prop1 = $localStorage.prop1;
$scope.prop2 = $localStorage.prop2;
存储值
$localStorage.prop1 = $scope.prop1;
$localStorage.prop2 = $scope.prop2;
请记住在应用程序中注入ngStorage,并在控制器中注入$localStorage。
有两种方法可以做到这一点
1( 使用获取/设置服务
2( $scope.$emit('key', {data: value}); //to set the value
$rootScope.$on('key', function (event, data) {}); // to get the value
第二种方法:
angular.module('myApp', [])
.controller('Ctrl1', ['$scope',
function($scope) {
$scope.prop1 = "First";
$scope.clickFunction = function() {
$scope.$broadcast('update_Ctrl2_controller', $scope.prop1);
};
}
])
.controller('Ctrl2', ['$scope',
function($scope) {
$scope.prop2 = "Second";
$scope.$on("update_Ctrl2_controller", function(event, prop) {
$scope.prop = prop;
$scope.both = prop + $scope.prop2;
});
}
])
目录 :
<div ng-controller="Ctrl2">
<p>{{both}}</p>
</div>
<button ng-click="clickFunction()">Click</button>
有关更多详细信息,请参阅plunker:
http://plnkr.co/edit/cKVsPcfs1A1Wwlud2jtO?p=preview
我查看了上面的答案,我推荐 pejman 的 Dec 29 '16 at 13:31 建议,但他/她没有留下完整的答案。 在这里,我将其作为 -->(您需要在控制器的一个作用域上$watch服务和侦听器,以更改服务区域(
var app =
angular.module('myApp', ['ngRoute', 'ngSanitize']);
app.service('bridgeService', function () {
var msg = "";
return msg;
});
app.controller('CTRL_1'
, function ($scope, $http, bridgeService)
{
$http.get(_restApi, config)
.success(
function (serverdata, status, config) {
$scope.scope1Box = bridgeService.msg = serverdata;
});
});
app.controller('CTRL_2'
, function ($scope, $http, bridgeService)
{
$scope.$watch( function () {
return (bridgeService.msg);
}, function (newVal, oldVal) {
$scope.scope2Box = newVal;
}, true
);
});
如果你不想做服务,那么你可以这样做。
var scope = angular.element("#another ctrl scope element id.").scope();
scope.plean_assign = some_value;
除了$rootScope和服务之外,还有一个干净简单的替代解决方案来扩展 angular 以添加共享数据:
在控制器中:
angular.sharedProperties = angular.sharedProperties
|| angular.extend(the-properties-objects);
此属性属于"角度"对象,与作用域分开,可以在作用域和服务中共享。
它的 1 个好处是您不必注入对象:在您定义后,它们可以立即在任何地方访问!
- 函数参数中的数据与指定变量之间的任何性能差异
- 全局变量和全局对象的属性之间有什么区别吗
- 在索引.html和应用.js [node.js] 之间共享变量
- 什么是&&在没有if的行中的变量之间
- 在JavaScript中,如何修复元素显示和变量创建之间的初始差异
- 在Knockoutjs中的ViewModels之间共享变量状态
- 在控制器之间传递变量的最佳方式
- 通过变量在两个数字之间切换
- 在函数之间传递javascript变量
- 在aspx页面c#之间传递/引用/发送变量/会话状态
- 在两个浏览器选项卡之间共享变量范围
- Javascript创建函数,以便在其他函数之间共享变量
- 关于node.js/javascript在文件之间共享变量
- AngularJS:如何在控制器之间传递变量
- 使用 AngularJS 在控制器之间传递变量
- 创建一个变量并在页面之间移动时“存储它”,jQuery
- 在 AngularJS 和非 AngularJS 弹出窗口之间共享变量
- 我需要在jQuery函数和AJAX之间获取一个变量
- 在Ember.js中的方法之间共享变量上下文
- 控制器之间变量名和数据的奇怪行为