247

製品を表示する基本的なコントローラーがあります。

App.controller('ProductCtrl',function($scope,$productFactory){
     $productFactory.get().success(function(data){
           $scope.products = data;
     });
});

私の見解では、この製品をリストに表示しています

<ul>
    <li ng-repeat="product as products">
        {{product.name}}
    </li>
</ul

私がやろうとしているのは、誰かが製品名をクリックしたときです。この製品が追加されたカートという名前の別のビューがあります。

 <ul class="cart">
      <li>
          //click one added here
      </li>
      <li>
          //click two added here
      </li>
 </ul>

ここで私の疑問は、このクリックされた製品を最初のコントローラーから2番目のコントローラーに渡す方法ですか? 私はカートもコントローラーであるべきだと思いました。

ディレクティブを使用してクリックイベントを処理します。また、上記の機能を実現するためにサービスを使用する必要があると感じていますが、どうすればよいですか? カートはあらかじめ定義されているため、追加される製品の数は、どのページのユーザーかによって 5/10 になる可能性があります。だから私はこのジェネリックを維持したいと思います。

アップデート:

ブロードキャストするサービスを作成し、2 番目のコントローラーでそれを受け取ります。クエリは、dom を更新するにはどうすればよいですか? 製品をドロップするリストはかなりハードコーディングされているためです。

4

18 に答える 18

324

説明から、サービスを使用する必要があるようです。http://egghead.io/lessons/angularjs-sharing-data-between-controllersおよびAngularJS Service Passing Data Between Controllersをチェックして、いくつかの例を確認してください。

製品サービスを (工場として) 次のように定義できます。

app.factory('productService', function() {
  var productList = [];

  var addProduct = function(newObj) {
      productList.push(newObj);
  };

  var getProducts = function(){
      return productList;
  };

  return {
    addProduct: addProduct,
    getProducts: getProducts
  };

});

依存関係により、両方のコントローラーにサービスが注入されます。

ProductControllerで、選択したオブジェクトを配列に追加するアクションを定義します。

app.controller('ProductController', function($scope, productService) {
    $scope.callToAddToProductList = function(currObj){
        productService.addProduct(currObj);
    };
});

CartControllerで、サービスから製品を取得します。

app.controller('CartController', function($scope, productService) {
    $scope.products = productService.getProducts();
});
于 2013-11-24T21:54:58.813 に答える
67

このクリックされた製品を最初のコントローラーから2番目のコントローラーに渡すにはどうすればよいですか?

クリックすると、ブロードキャストを呼び出すメソッドを呼び出すことができます:

$rootScope.$broadcast('SOME_TAG', 'your value');

2 番目のコントローラーは、次のようにこのタグをリッスンします。

$scope.$on('SOME_TAG', function(response) {
      // ....
})

$scope をサービスに注入できないため、シングルトン $scope のようなものはありません。

しかし、注入することはでき$rootScopeます。$rootScope.$broadcast('SOME_TAG', 'your value');したがって、サービスに値を格納すると、サービス本体で実行できます。(サービスについては @Charx の説明を参照)

app.service('productService',  function($rootScope) {/*....*/}

$broadcast$emitについての良い記事を確認してください

于 2013-11-24T21:42:44.010 に答える
25

$rootScope を使用して、サービスを作成しないソリューション:

アプリ コントローラー間でプロパティを共有するには、Angular $rootScope を使用できます。これはデータを共有するためのもう 1 つのオプションであり、人々がそれについて知ることができるようにします。

コントローラー間でいくつかの機能を共有するための推奨される方法はサービスです。グローバル プロパティを読み取ったり変更したりするには、$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>
于 2014-08-27T19:00:56.460 に答える
16

これは 2 つの方法で行うことができます。

  1. を使用し$rootscopeますが、これはお勧めしません。は$rootScope最上位のスコープです。$rootScopeアプリは、アプリのすべてのコンポーネント間で共有される1 つのみを持つことができます。したがって、グローバル変数のように機能します。

  2. サービスの使用。これを行うには、2 つのコントローラー間でサービスを共有します。サービスのコードは次のようになります。

    app.service('shareDataService', function() {
        var myList = [];
    
        var addList = function(newObj) {
            myList.push(newObj);
        }
    
        var getList = function(){
            return myList;
        }
    
        return {
            addList: addList,
            getList: getList
        };
    });
    

    ここで私のフィドルを見ることができます。

于 2015-02-12T18:08:47.410 に答える
8
angular.module('testAppControllers', [])
    .controller('ctrlOne', function ($scope) {
        $scope.$broadcast('test');
    })
    .controller('ctrlTwo', function ($scope) {
        $scope.$on('test', function() {
        });
    });
于 2016-01-26T08:32:33.443 に答える
7

ここで回答を見ました。コントローラー間でデータを共有するという質問に答えていますが、一方のコントローラーに、データが変更されたことを (ブロードキャストを使用せずに) 他のコントローラーに通知させたい場合はどうすればよいですか? 簡単!有名な訪問者パターンを使用するだけです:

myApp.service('myService', function() {

    var visitors = [];

    var registerVisitor = function (visitor) {
        visitors.push(visitor);
    }

    var notifyAll = function() {
        for (var index = 0; index < visitors.length; ++index)
            visitors[index].visit();
    }

    var myData = ["some", "list", "of", "data"];

    var setData = function (newData) {
        myData = newData;
        notifyAll();
    }

    var getData = function () {
        return myData;
    }

    return {
        registerVisitor: registerVisitor,
        setData: setData,
        getData: getData
    };
}

myApp.controller('firstController', ['$scope', 'myService',
    function firstController($scope, myService) {

        var setData = function (data) {
            myService.setData(data);
        }

    }
]);

myApp.controller('secondController', ['$scope', 'myService',
    function secondController($scope, myService) {

        myService.registerVisitor(this);

        this.visit = function () {
            $scope.data = myService.getData();
        }

        $scope.data = myService.getData();
    }
]);

この単純な方法で、1 つのコントローラーが、一部のデータが更新された別のコントローラーを更新できます。

于 2015-04-06T08:10:53.637 に答える
3

ルート パスのパターン間の共有スコープを制御するファクトリを作成したので、ユーザーが同じルートの親パスをナビゲートしているときに共有データを維持できます。

.controller('CadastroController', ['$scope', 'RouteSharedScope',
    function($scope, routeSharedScope) {
      var customerScope = routeSharedScope.scopeFor('/Customer');
      //var indexScope = routeSharedScope.scopeFor('/');
    }
 ])

そのため、ユーザーが「/Support」などの別のルート パスに移動すると、パス「/Customer」の共有データは自動的に破棄されます。ただし、これの代わりにユーザーが「/Customer/1」や「/Customer/list」などの「子」パスに移動した場合、スコープは破棄されません。

ここでサンプルを見ることができます: http://plnkr.co/edit/OL8of9

于 2014-09-19T02:05:20.917 に答える
3

誰にも役立つかどうかはわかりませんが、Charx (ありがとう!) の回答に基づいて、単純なキャッシュ サービスを作成しました。自由に使用、リミックス、共有してください:

angular.service('cache', function() {
    var _cache, _store, _get, _set, _clear;
    _cache = {};

    _store = function(data) {
        angular.merge(_cache, data);
    };

    _set = function(data) {
        _cache = angular.extend({}, data);
    };

    _get = function(key) {
        if(key == null) {
            return _cache;
        } else {
            return _cache[key];
        }
    };

    _clear = function() {
        _cache = {};
    };

    return {
        get: _get,
        set: _set,
        store: _store,
        clear: _clear
    };
});
于 2016-10-03T19:09:12.553 に答える
2

angular サービスを使用する 1 つの方法:

var app = angular.module("home", []);

app.controller('one', function($scope, ser1){
$scope.inputText = ser1;
});


app.controller('two',function($scope, ser1){
$scope.inputTextTwo = ser1;
});

app.factory('ser1', function(){
return {o: ''};
});



<div ng-app='home'>

<div ng-controller='one'>
  Type in text: 
  <input type='text' ng-model="inputText.o"/>
</div>
<br />

<div ng-controller='two'>
  Type in text:
  <input type='text' ng-model="inputTextTwo.o"/>
</div>

</div>

https://jsfiddle.net/1w64222q/

于 2016-12-07T18:51:08.740 に答える
1

やり方は3つあるのですが、

a) サービスの使用

b) コントローラ スコープ間の親子関係の依存関係を利用する。

c) Angular 2.0 では、"As" キーワードは、あるコントローラーから別のコントローラーにデータを渡します。

例の詳細については、以下のリンクを確認してください。

http://www.tutorial-points.com/2016/03/angular-js.html

于 2016-03-18T07:47:54.090 に答える
1

参考までに、$scope オブジェクトには $emit、$broadcast、$on があり、$rootScope オブジェクトには同じ $emit、$broadcast、$on があります

Angular のパブリッシュ/サブスクライブ デザイン パターンの詳細については、こちらをご覧ください

于 2015-11-17T18:04:57.687 に答える