javascript 在 AngularJS 服务中处理数据绑定
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14527377/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Handling data binding in AngularJS Services
提问by Aidan Kane
I'm trying to figure out how you handle binding properly when my data is stored in a service.
我试图弄清楚当我的数据存储在服务中时如何正确处理绑定。
I can get things working if it put the service into the $scope and then get the templates to bind directly into it but that seems like a really bad idea.
如果将服务放入 $scope 中,然后将模板直接绑定到它,我可以让事情正常工作,但这似乎是一个非常糟糕的主意。
I'd basically like to have it so that my views / controllers are able to easily change the state down in a service and have that reflected everywhere.
我基本上希望拥有它,以便我的视图/控制器能够轻松地更改服务中的状态并将其反映到任何地方。
It feels like I should be able to do something like the following, but it doesn't work (http://jsfiddle.net/aidankane/AtRVD/1/).
感觉我应该能够做类似以下的事情,但它不起作用(http://jsfiddle.net/aidankane/AtRVD/1/)。
HTML
HTML
<div ng-controller="MyCtl">
<select ng-model="drawing" ng-options="d.file for d in drawings"></select>
</div>
<div ng-controller="MyOtherCtl">
{{ drawing }}
</div>
JS
JS
var myApp = angular.module('myApp', []);
myApp.factory('myService', function(){
var me = {
drawings: [{'file':'a'}, {'file':'b'}]
};
// selected drawing
me.drawing = me.drawings[0];
return me;
});
function MyCtl($scope, myService){
// can do:
// $scope.mys = myService;
// and then in html ng-model="mys.drawing"
// but that seems wrong
$scope.drawings = myService.drawings;
$scope.drawing = myService.drawing;
// can I not do this? it doesn't seem to work anyway...
$scope.$watch('drawing', function(drawing){
myService.drawing = drawing;
});
}
function MyOtherCtl($scope, myService){
$scope.drawing = myService.drawing;
}
MyCtl.$inject = ['$scope', 'myService'];
MyOtherCtl.$inject = ['$scope', 'myService'];
回答by Josh David Miller
You can bind to services using $watch
and passing a function:
您可以使用$watch
和传递函数绑定到服务:
$scope.$watch( function () { return myService.drawing; }, function ( drawing ) {
// handle it here. e.g.:
$scope.drawing = drawing;
});
And then use $scope.drawing
in your templates and they will automatically update:
然后$scope.drawing
在您的模板中使用,它们将自动更新:
<div ng-controller="MyOtherCtl">
{{ drawing }}
</div>
回答by Bart?omiej Zalewski
I think, even more elegant is to work with promises (see $q.deferred()
) and to resolve them asynchronously. In the promise function you can then assign the data to $scope
's members.
我认为,更优雅的是使用 Promise(请参阅 参考资料$q.deferred()
)并异步解决它们。在 promise 函数中,您可以将数据分配给$scope
的成员。
回答by Nick Brady
There are two ways to do bind the data from a service: 1) By value (will require a watcher as done above to check for variable changes to the service primitive value) 2) By reference (values are directly linked) which is my preferred method of data binding.
有两种方法可以绑定来自服务的数据:1)按值(需要一个观察者,如上所述检查服务原始值的变量更改)2)按引用(值直接链接)这是我的首选数据绑定方法。
I will only explain the second possibility since the accepted answer already shows how a watcher can be implemented. This blog describes what I am going to explain very well.
我将只解释第二种可能性,因为接受的答案已经显示了如何实现观察者。这篇博客很好地描述了我将要解释的内容。
I created this plunk to illustrate data binding by reference.
Here is the code from the plunk:
这是来自plunk的代码:
HTML
HTML
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script data-require="[email protected]" data-semver="1.5.0" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="myAppCntrl">
<h1>Hello Plunker!</h1>
<h3>By value</h3>
<p>{{byValue}}</p>
<p>{{objByValue}}</p>
<h3>By object in service reference</h3>
<p>{{byRefence.stringPrimitive}}</p>
<h3>By reference to service singleton</h3>
<p>{{myservice.stringPrimitive}}</p>
<p style="color: green">of course, you can reference an object through the service as well</p>
<p>{{myservice.objectWithPrimitive.stringPrimitive}}</p>
<button ng-click=update()>Update strings on service</button>
<br />
<button ng-click=setDefaults()>Restore Defaults</button>
</body>
</html>
JAVASCRIPT
爪哇脚本
var myApp = angular.module("myApp", []);
myApp.controller('myAppCntrl', function($scope, myAppService){
$scope.myservice = myAppService;
$scope.byValue = myAppService.stringPrimitive;
$scope.objByValue = myAppService.objectWithPrimitive.stringPrimitive;
$scope.byRefence = myAppService.objectWithPrimitive;
$scope.update = function () {
myAppService.stringPrimitive = "updated string";
myAppService.objectWithPrimitive.stringPrimitive = "updated string here too";
};
$scope.setDefaults = function () {
myAppService.stringPrimitive = 'string primitive';
myAppService.objectWithPrimitive.stringPrimitive = 'string primitive';
};
});
myApp.service('myAppService', function(){
this.stringPrimitive = 'string primitive';
this.objectWithPrimitive = {
stringPrimitive: 'string primitive'
};
});
So how does this work?
那么这是如何工作的呢?
It is important to understand that this has little to do with how angular works, and a lot to do with how Javascript works. When a variable is set equal to a primitive value (or passed to a function) in javascript (integer, string, etc.) the var is set by value. This means that the the new variable is a copy of the variable you are setting it equal to with a new location in memory. When a variable is set equal to an object (or passed to a function) in javascript the var is set by reference.
重要的是要了解这与 angular 的工作方式无关,而与 Javascript 的工作方式有很大关系。当一个变量被设置为等于一个原始值(或传递给一个函数)在 javascript(整数、字符串等)中时,var 是由 value 设置的。这意味着新变量是您将其设置为等于内存中新位置的变量的副本。当一个变量在 javascript 中被设置为一个对象(或传递给一个函数)时,var 是通过引用设置的。
What does this mean?
这是什么意思?
When a $scope var is set by value, and the service variable changes, since the $scope variable is only a copy of the service variable, the service variable no longer has anything to do with the service variable and will not change when the service var does.
当一个$scope var被值设置,并且service变量发生变化时,由于$scope变量只是service变量的一个副本,service变量不再与service变量有任何关系,不会在service的时候发生变化var 确实如此。
When the $scope var is set equal to and object, it is assigned by Reference. This means that when the service object (note that the service is an object since it is instantiated with the new keyword and you can refer to that object with "this" inside the service) or any objects on the service that are referenced are changed, any $scope variable that reference those objects will update as well.
当 $scope var 设置为等于和 object 时,它由 Reference 分配。这意味着当服务对象(请注意,该服务是一个对象,因为它是用 new 关键字实例化的,您可以在服务内部使用“this”来引用该对象)或服务上引用的任何对象发生更改,任何引用这些对象的 $scope 变量也将更新。