$ scope和这些技术在通过服务共享数据方面有何不同?

时间:2017-05-21 06:01:13

标签: javascript html angularjs angularjs-scope

如果您要创建新代码,请不要更改原始jsbins

我正在以角度1编写应用程序。现在我需要创建一个可以在多个控制器中注入的服务。我还需要在各种控制器中更改数据,但反映控制器的变化。所以我想我想要的是具有双向绑定的全局值。我一直在使用" var vm = this"技术而不是使用$ scope。我已经读过它们除语法外基本相同。但是我有两个例子,在创建不同的结果时会有相同的目标。

他们都分享这项服务:

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

app.service('sharedProperties', function() {
    var stringValue = 'test string value';
    var objectValue = {
        data: 'test object value'
    };

    return {
        getString: function() {
            return stringValue;
        },
        setString: function(value) {
            stringValue = value;
        },
        getObject: function() {
            return objectValue;
        }
    }
});

我已经设置了两个jsbin来显示它们的功能。

这是"这个"例: http://jsbin.com/conidesuni/edit?html,js,output

这是$ scope示例: http://jsbin.com/gobodutaje/edit?html,js,output

有两个输入源,一个绑定到objectValue,另一个绑定到objectValue和stringValue。在设置两个值的输入中,调用服务的set函数。

区别在于$ scope似乎绑定在控制器2中的两个绑定div中,但是"这个"例子不是这样做的。尝试同时更改两个值时,此示例不会更改任何值(stringValue和objectValue)。它在控制台中打印undefined。

这两种技术都不会导致controller2中的输入更改控制器1中的div,尽管它们共享服务。

我想知道如何在控制器之间通过两种方式绑定这两种方式,以及"这个"之间的区别究竟是什么?示例和$ scope示例。

2 个答案:

答案 0 :(得分:1)

基本上$scopethis与您在问题中所说的相同。

在模板中检索ControllerAsmyController2 as cont2)时,要从模板访问控制器的所有内容(变量和函数)必须具有cont2的前缀。

在您的第一个jsbin中,您在调用cont2时错过了一个前缀cont2.setString(newValue),它应该是cont2.setString(cont2.newValue)。否则你无法通过你在文本框中输入的内容。

<强> UPD:

通常,如果sharedService的值变化,我们必须手动调用服务函数来获取@Sumit Deshpande所回答的newValue。

还有另一种方法可以将相同的对象实例绑定到控制器的变量,并保存在sharedService中的对象实例,但请记住,这种方式并不是这样的支持字符串类型的字段(除非您将字符串归档到对象字段中)。

请参阅以下 plunker

答案 1 :(得分:1)

要在服务中发生变更时反映数据,有两种方法可以做到 -

  1. 使用发布者订阅者机制在服务变量/对象发生更改时广播和监听。
  2. 通过服务方法直接绑定来实现同样的目的。
  3. 以下是2# -

    的示例代码
    app.controller('myController1', function($timeout, sharedProperties) {
        var vm = this;
        vm.service = sharedProperties;
    });
    
    app.controller('myController2', function(sharedProperties) {        
        var vm = this;
        vm.service = sharedProperties;  
        vm.setString = function(newValue) 
        {   console.log(newValue);
            vm.objectValue.data = newValue;
            vm.service.setString(newValue);
        };
    });
    

    HTML

    <div ng-app="myApp">
        <div ng-controller="myController1 as cont1">
          <ul>
            <li><b>myController1</b> (values won't change)</li>
            <li>{{cont1.service.getString()}}</li>
            <li>{{cont1.service.getObject()}}</li>
          </ul>
        </div>    
        <div ng-controller="myController2 as cont2">
          <ul>
            <li><b>myController2</b> (values will change when Set Values is clicked or when 2-way binding textbox is modified)</li>
            <li>{{cont2.service.getString()}}</li>
            <li>{{cont2.service.getObject().data}}</li>
          </ul>
          <input type="text" ng-model="cont2.newValue"></input>
        <button ng-click="cont2.setString(cont2.newValue)">Set Values</button><br/>
        <input type="text" ng-model="cont2.objectValue.data"></input>2-way binding to objectValue
      </div>
      </div>