Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/413.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在AngularJS服务中处理数据绑定_Javascript_Service_Binding_Angularjs - Fatal编程技术网

Javascript 在AngularJS服务中处理数据绑定

Javascript 在AngularJS服务中处理数据绑定,javascript,service,binding,angularjs,Javascript,Service,Binding,Angularjs,我试图弄清楚,当我的数据存储在服务中时,如何正确处理绑定 如果它将服务放入$scope中,然后将模板直接绑定到其中,我可以让事情正常进行,但这似乎是一个非常糟糕的主意 基本上,我希望我的视图/控制器能够轻松地更改服务中的状态,并将其反映到所有地方 我觉得我应该可以做如下的事情,但它不起作用(http://jsfiddle.net/aidankane/AtRVD/1/) HTML 您可以使用$watch并传递函数绑定到服务: $scope.$watch(函数(){return myService.

我试图弄清楚,当我的数据存储在服务中时,如何正确处理绑定

如果它将服务放入$scope中,然后将模板直接绑定到其中,我可以让事情正常进行,但这似乎是一个非常糟糕的主意

基本上,我希望我的视图/控制器能够轻松地更改服务中的状态,并将其反映到所有地方

我觉得我应该可以做如下的事情,但它不起作用(http://jsfiddle.net/aidankane/AtRVD/1/)

HTML


您可以使用
$watch
并传递函数绑定到服务:

$scope.$watch(函数(){return myService.drawing;},函数(drawing){
//在这里处理。例如:
$scope.drawing=图纸;
});
然后在模板中使用
$scope.drawing
,它们将自动更新:


{{绘图}}

我认为,更优雅的做法是使用承诺(请参见
$q.deferred()
)并异步解决它们。然后,在promise函数中,您可以将数据分配给
$scope
的成员。

有两种方法可以从服务绑定数据:1)通过值(需要如上所述的观察者检查服务原语值的变量更改)2)通过引用(值直接链接)哪种是我首选的数据绑定方法。

我将只解释第二种可能性,因为公认的答案已经说明了如何实现观察者

以下是来自plunk的代码:

HTML

那么这是如何工作的呢

重要的是要理解,这与angular的工作原理关系不大,而与Javascript的工作原理关系很大。当变量设置为javascript(整数、字符串等)中的基元值(或传递给函数)时,变量由值设置。这意味着新变量是将其设置为与内存中的新位置相等的变量的副本。在javascript中将变量设置为等于对象(或传递给函数)时,通过引用设置变量

这是什么意思

当$scope变量由值设置,并且服务变量发生变化时,由于$scope变量只是服务变量的副本,因此服务变量不再与服务变量有任何关系,并且在服务变量发生变化时不会发生变化


当$scope变量设置为等于and对象时,它将通过引用进行赋值。这意味着当服务对象(请注意,该服务是一个对象,因为它是用new关键字实例化的,您可以在服务中用“This”引用该对象)或服务上被引用的任何对象发生更改时,引用这些对象的任何$scope变量也将更新。

我看到您正在查看$scope.drawing的更改位置,但您没有更改模型,您正在更改所选项目。您不应该为所选项目的更改(可能是在指令中)添加处理程序吗?如何使用指令执行此操作?我认为ngSelect指令基本上提供了我需要的行为。我对这个问题的理解是,控制器和服务之间的移动才是问题所在——然后我现在又有点困惑:)你是对的,现在我看到了你更新的小提琴,我对你在尝试什么有了更好的了解。你没有困惑:)好的。我想这让我走上了正确的道路。因此,我创建了一个新版本--并且在两个方向上创建了观察者,以在服务之间推/拉。这是正确的做法吗?@AidanKane Yep!组件间通信是此处和邮件列表中的常见问题。到目前为止,服务是最常见的(通常是更“正确的”)解决方案。我很早就看到,它们是保存数据的正确方式。只是在服务/控制器/视图之间的协调方面有些困难。似乎通过使用该服务,我必须在控制器中添加一些样板文件来同步内容(控制器中的内容太少了,我不介意)。感谢您的及时回复,谢谢。通常会有,但这取决于上下文。例如,您可以只做
$scope.drawing=myService.drawing
,完全避免观看,但从关注点分离的角度来看,这通常是不赞成的。如果你有一个例子,我相信我们可以找到一些不那么一般、不那么冗长的东西。@mariachimike没错,但总有例外。如果你只加载一次数据就可以了,但我认为正在更改的数据不会像OP所寻找的那样自动绑定。可能是错的。
<div ng-controller="MyCtl">
    <select ng-model="drawing" ng-options="d.file for d in drawings"></select>
</div>
<div ng-controller="MyOtherCtl">
    {{ drawing }}
</div>
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'];
<!DOCTYPE html>
<html ng-app="myApp">

  <head>
    <script data-require="angularjs@1.5.0" 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>
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'
  };
});