AngularJS: Как создать двустороннюю привязку данных между двумя изолированными контроллерами и совместно используемой услугой?

Я пытаюсь создать двустороннюю привязку данных между двумя изолированными контроллерами и общей службой (которая предоставляет еще одну изолированную область):

app.factory("sharedScope", function($rootScope) {
    var scope = $rootScope.$new(true);
    scope.data = "init text from factory";
    return scope;
});

app.controller("first", function($scope, sharedScope) {
    $scope.data1 = sharedScope.data;
});

app.controller("second", function($scope, sharedScope) {
    $scope.data2 = sharedScope.data;
});

Fiddle: http://jsfiddle.net/akashivskyy/MLuJA/

Когда приложение запускается, data1 и data2 корректно обновляются до init text from factory, но позже, если я изменю любой из них, эти изменения не будут отображаться в этих трех областях.

Как я могу связать их?

P.S. Если есть лучший способ, чем вернуть область действия и все еще иметь доступ к событиям и наблюдениям (без их перезаписи), дайте мне знать.:)

Ответ 1

Исправлено. Ссылки будут потеряны, если вы используете примитивы, как в вашей скрипке.

Проверьте это:

Обновлена ​​скрипка

app.factory("sharedScope", function($rootScope) {
    var scope = $rootScope.$new(true);
    scope.data = {text: "init text from factory"};
    return scope;
});

app.controller("first", function($scope, sharedScope) {
    $scope.data1 = sharedScope.data;
});

app.controller("second", function($scope, sharedScope) {
    $scope.data2 = sharedScope.data;
});

Ответ 2

Еще один забавный бит: в этом случае вам не нужно вводить $scope или $rootScope. Следующий код работает, если вы используете Controller As. Проверьте Fiddle

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

app.factory("sharedScope", function() {
    var _this = this;
    _this.data = {text: "init text from factory"};
    return _this;
});

app.controller("first", function(sharedScope) {
    var _this = this;
    _this.data1 = sharedScope.data;
});

app.controller("second", function(sharedScope) {
    var _this = this;
    _this.data2 = sharedScope.data;
});

Для еще большего удовольствия рассмотрите контроллеры, службы и фабрики как классы. Другие скрипты

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

var SharedScope = function(){
    var _this = this;
    _this.data = {text: "init text from factory"};
    return _this;
};

app.factory("sharedScope", SharedScope);

var First = function(sharedScope){
    var _this = this;
    _this.data1 = sharedScope.data;
};

var Second = function(sharedScope){
    var _this = this;
    _this.data2 = sharedScope.data;
};

First.$inject = ['sharedScope'];
Second.$inject = ['sharedScope'];

app.controller("first", First);              
app.controller("second", Second);

Я играю при реализации Josh Carroll Руководства, чтобы избежать "Суп-суп"

Ответ 3

JavaScript передает объекты по ссылке, поэтому все области будут указывать на один и тот же объект. Почему бы просто не сделать это?

app.factory("sharedData", function() {
    return {data: "init text from factory"};
});

app.controller("first", function($scope, sharedData) {
    $scope.sharedData = sharedData;
});

app.controller("second", function($scope, sharedData) {
    $scope.sharedData = sharedData;
});

и на ваш взгляд:

<p>{{sharedData.data}}</p>