$scope 和这种技术在通过服务共享数据方面有何不同?
How do $scope and this techniques differ in terms of sharing data via services?
如果您要创建新代码,请不要更改原始 jsbins
我正在 angular 中编写一个应用程序。现在我需要创建一个可以注入多个控制器的服务。我还需要数据在各种控制器中是可变的,但反映了控制器之间的变化。所以我想我想要的是具有 2 种方式绑定的全局值。我一直在使用 "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 来展示它们的功能。
这是 "this" 示例:
http://jsbin.com/conidesuni/edit?html,js,output
这是 $scope 示例:
http://jsbin.com/gobodutaje/edit?html,js,output
有两种输入源,一种绑定到 objectValue,另一种绑定到 objectValue 和 stringValue。在设置这两个值的输入中,调用服务的设置函数。
不同之处在于 $scope 似乎绑定了控制器二中的两个绑定 div,但 "this" 示例并未这样做。此示例在尝试同时更改两个值(stringValue 和 objectValue)时未更改任何值。它在控制台中打印未定义。
这两种技术都不会导致 controller2 中的输入更改 controller1 中的 div,尽管它们共享服务。
我想知道如何在控制器之间以两种方式进行这些绑定,以及 "this" 示例和 $scope 示例之间的确切区别。
基本上 $scope
和 this
与您在问题中所说的相同。
当您在模板中检索 ControllerAs
(myController2 as cont2
) 时,您想要从模板访问到控制器的所有内容(变量和函数)都必须具有前缀 cont2
。
并且在您的第一个 jsbin 中,您在调用 cont2.setString(newValue)
时错过了一个前缀 cont2
,它应该是 cont2.setString(cont2.newValue)
。否则你不能传递你在文本框中输入的内容。
UPD:
通常,如果 sharedService 的值 lept 发生变化,我们必须手动调用服务函数来获取新值,正如@Sumit Deshpande 所回答的那样。
还有另一种方法可以将相同的对象实例绑定到控制器的变量,对象实例保存在sharedService中,但请记住,这种方式不支持字符串类型的字段(除非你把字符串字段也放在对象字段中)。
参考下面plunker.
要在服务发生变化时反映数据,有两种方法可以做到这一点 -
- 当服务发生变化时,使用发布者订阅者机制进行广播和监听variable/object。
- 直接通过service方法绑定即可达到同样效果
这里是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>
如果您要创建新代码,请不要更改原始 jsbins
我正在 angular 中编写一个应用程序。现在我需要创建一个可以注入多个控制器的服务。我还需要数据在各种控制器中是可变的,但反映了控制器之间的变化。所以我想我想要的是具有 2 种方式绑定的全局值。我一直在使用 "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 来展示它们的功能。
这是 "this" 示例: http://jsbin.com/conidesuni/edit?html,js,output
这是 $scope 示例: http://jsbin.com/gobodutaje/edit?html,js,output
有两种输入源,一种绑定到 objectValue,另一种绑定到 objectValue 和 stringValue。在设置这两个值的输入中,调用服务的设置函数。
不同之处在于 $scope 似乎绑定了控制器二中的两个绑定 div,但 "this" 示例并未这样做。此示例在尝试同时更改两个值(stringValue 和 objectValue)时未更改任何值。它在控制台中打印未定义。
这两种技术都不会导致 controller2 中的输入更改 controller1 中的 div,尽管它们共享服务。
我想知道如何在控制器之间以两种方式进行这些绑定,以及 "this" 示例和 $scope 示例之间的确切区别。
基本上 $scope
和 this
与您在问题中所说的相同。
当您在模板中检索 ControllerAs
(myController2 as cont2
) 时,您想要从模板访问到控制器的所有内容(变量和函数)都必须具有前缀 cont2
。
并且在您的第一个 jsbin 中,您在调用 cont2.setString(newValue)
时错过了一个前缀 cont2
,它应该是 cont2.setString(cont2.newValue)
。否则你不能传递你在文本框中输入的内容。
UPD:
通常,如果 sharedService 的值 lept 发生变化,我们必须手动调用服务函数来获取新值,正如@Sumit Deshpande 所回答的那样。
还有另一种方法可以将相同的对象实例绑定到控制器的变量,对象实例保存在sharedService中,但请记住,这种方式不支持字符串类型的字段(除非你把字符串字段也放在对象字段中)。
参考下面plunker.
要在服务发生变化时反映数据,有两种方法可以做到这一点 -
- 当服务发生变化时,使用发布者订阅者机制进行广播和监听variable/object。
- 直接通过service方法绑定即可达到同样效果
这里是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>