20

私のデータがサービスに保存されているときにバインディングを適切に処理する方法を理解しようとしています。

サービスを $scope に入れてから、テンプレートを直接バインドするようにすればうまくいきますが、それは本当に悪い考えのようです。

基本的に、ビュー/コントローラーがサービスの状態を簡単に変更して、それをどこにでも反映できるようにしたいと考えています。

次のようなことができればいいような気がしますが、うまくいきません (http://jsfiddle.net/aidankane/AtRVD/1/)。

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

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'];
4

3 に答える 3

41

$watch関数を使用して渡すことで、サービスにバインドできます。

$scope.$watch( function () { return myService.drawing; }, function ( drawing ) {
  // handle it here. e.g.:
  $scope.drawing = drawing;
});

次に$scope.drawing、テンプレートで使用すると、テンプレートが自動的に更新されます。

<div ng-controller="MyOtherCtl">
  {{ drawing }}
</div>
于 2013-01-25T17:46:59.583 に答える
2

サービスからデータをバインドするには、次の 2 つの方法があります。1) 値による (サービス プリミティブ値への変数の変更を確認するには、上記のようにウォッチャーが必要です) 2) 参照による (値は直接リンクされています) これが私の好みですデータバインディングの方法。

受け入れられた回答はすでにウォッチャーの実装方法を示しているため、2番目の可能性についてのみ説明します。このブログでは、私が説明しようとしていることを非常によく説明しています

このプランクは、参照によるデータ バインディングを説明するために作成しました。

プランクのコードは次のとおりです。

HTML

<!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'
  };
});

では、これはどのように機能するのでしょうか。

これは angular の仕組みとはほとんど関係がなく、Javascript の仕組みと大きく関係していることを理解することが重要です。変数が javascript (整数、文字列など)のプリミティブ値と等しく設定される (または関数に渡される) 場合、var は value によって設定されます。これは、新しい変数が、メモリ内の新しい場所と等しくなるように設定している変数のコピーであることを意味します。変数が JavaScript でオブジェクトと等しく設定される (または関数に渡される) 場合、var は参照によって設定されます

これは何を意味するのでしょうか?

$scope 変数が値によって設定され、サービス変数が変更されると、$scope 変数はサービス変数のコピーにすぎないため、サービス変数はサービス変数とは何の関係もなく、サービスが変更されても変更されません。 var です。

$scope 変数がオブジェクトと等しく設定されている場合、参照によって割り当てられます。これは、サービス オブジェクト (サービスは new キーワードでインスタンス化され、サービス内で「this」を使用してそのオブジェクトを参照できるため、サービスはオブジェクトであることに注意してください) または参照されるサービス上のオブジェクトが変更された場合を意味します。これらのオブジェクトを参照する $scope 変数も更新されます。

于 2016-03-05T23:14:43.390 に答える
2

$q.deferred()私は、Promise (参考文献を参照) を操作し、それらを非同期的に解決する方がよりエレガントだと思います。$scopepromise 関数では、データをのメンバーに割り当てることができます。

于 2014-09-08T11:30:19.877 に答える