在AngularJS服务中处理数据绑定
在AngularJS服务中处理数据绑定
我正在尝试弄清楚当我的数据存储在一个服务中时,如何正确处理绑定。如果我将服务放入$scope中,然后让模板直接与之绑定,我可以让一切正常工作,但这似乎是一个非常糟糕的主意。实际上,我希望我的视图/控制器能够轻松地改变服务中的状态,并且在所有地方都能反映出来。我感觉应该能够做到像以下这样的事情,但它不起作用(http://jsfiddle.net/aidankane/AtRVD/1/)。\nHTML:\n
{{ drawing }}
\nJS:\n
var myApp = angular.module('myApp', []); myApp.factory('myService', function(){ var me = { drawings: [{'file':'a'}, {'file':'b'}] }; // 选择的图形 me.drawing = me.drawings[0]; return me; }); function MyCtl($scope, myService){ // 可以这样做: // $scope.mys = myService; // 然后在html中使用ng-model="mys.drawing" // 但这似乎不对 $scope.drawings = myService.drawings; $scope.drawing = myService.drawing; // 我不能这样做吗?它似乎无效... $scope.$watch('drawing', function(drawing){ myService.drawing = drawing; }); } function MyOtherCtl($scope, myService){ $scope.drawing = myService.drawing; } MyCtl.$inject = ['$scope', 'myService']; MyOtherCtl.$inject = ['$scope', 'myService'];
AngularJS中处理数据绑定的问题是什么以及解决方法是什么?
问题:在AngularJS中,有两种方法可以绑定服务中的数据:1)按值绑定(将需要一个监视器来检查服务原始值的变化)2)按引用绑定(值直接链接)。我只解释第二种可能性,因为已经有人展示了如何实现监视器。
解决方法:通过引用进行数据绑定。在AngularJS中,当将$scope变量设置为对象时,它是通过引用赋值的。这意味着当服务对象或引用的任何对象发生变化时,引用这些对象的$scope变量也会更新。
下面是一个示例代码,用于演示通过引用进行数据绑定的方法:
HTML
Hello Plunker!
By value
{{byValue}}
{{objByValue}}
By object in service reference
{{byRefence.stringPrimitive}}
By reference to service singleton
{{myservice.stringPrimitive}}
of course, you can reference an object through the service as well
{{myservice.objectWithPrimitive.stringPrimitive}}
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' }; });
这个示例代码中的$scope变量通过引用绑定到myAppService服务中的变量。当服务对象或引用的任何对象发生更改时,$scope变量也会更新。
处理数据绑定的问题出现的原因是当数据发生变化时,使用$q.deferred()解决方案无法自动绑定数据。下面是解决方法:
通过在服务中使用$q.deferred(),并在异步地解决它们的承诺函数中将数据分配给$scope的成员,可以解决这个问题。这样,当数据发生变化时,数据将自动绑定到$scope。
示例代码如下:
var app = angular.module('myApp', []); app.service('myService', function($http, $q) { this.getData = function() { var deferred = $q.defer(); $http.get('data.json') .then(function(response) { deferred.resolve(response.data); }, function(error) { deferred.reject(error); }); return deferred.promise; } }); app.controller('myCtrl', function($scope, myService) { myService.getData() .then(function(data) { $scope.myData = data; }, function(error) { console.log(error); }); });
在这个例子中,我们首先创建了一个名为myApp的AngularJS应用程序,并定义了一个名为myService的服务。在myService中,我们使用$q.deferred()创建了一个承诺,并在$http.get请求成功时通过deferred.resolve()方法解决这个承诺。然后,我们在myCtrl控制器中使用myService来获取数据,并在成功时将数据分配给$scope.myData。
通过使用这种方法,我们可以在数据发生变化时自动绑定数据,从而解决了处理数据绑定的问题。
处理AngularJS服务中的数据绑定的问题是因为需要在服务和控制器之间同步数据,而且希望能够实现双向绑定。解决方法是使用$watch函数进行数据绑定,并在函数中处理数据的更新。首先,在控制器中使用$watch函数监听服务中的数据,然后在回调函数中更新控制器中的数据。接下来,在模板中使用$scope.drawing来展示更新后的数据。
另外,可以在服务和控制器之间创建双向绑定,通过在两者之间设置watchers来进行数据的推送和拉取。这是处理组件间通信的常见问题,而服务通常是最常见且通常更“正确”的解决方案。
虽然直接使用$scope.drawing = myService.drawing可以实现绑定,但从关注点分离的角度来看,这种做法通常不被推荐。尽管如此,根据具体情况也可能有例外。
在处理服务和控制器之间的数据绑定时,需要为每个具有双向绑定需求的服务设置这些绑定,这可能显得冗长和笨拙。但是,根据具体情况,通常还有其他方法来解决这个问题。
处理AngularJS服务中的数据绑定问题需要使用$watch函数进行监听和更新数据,并在控制器和模板中使用相应的变量来展示数据。尽管直接绑定数据可能会导致紧密耦合,但在某些情况下也可以采用这种方式。