在AngularJS中,我们的确有手动运行模板编译的能力。例如,插值允许基于作用域上的某
个条件实时更新文本字符串。
要在字符串模板中做插值操作,需要在你的对象中注入$interpolate服务。在下面的例子中,我们将会将它注入到一个控制器中:
angular.module('myApp', [])
.controller('MyController',
function($scope, $interpolate) {
// 我们同时拥有访问$scope和$interpolate服务的权限
}); 10$interpolate服务是一个可以接受三个参数的函数,其中第一个参数是必需的。
11
达式时会返回null。 12 trustedContext(字符串):AngularJS会对已经进行过字符插值操作的字符串通过
text(字符串):一个包含字符插值标记的字符串。
mustHaveExpression(布尔型):如果将这个参数设为true,当传入的字符串中不含有表
$sec.getTrusted()方法进行严格的上下文转义
$interpolate服务返回一个函数,用来在特定的上下文中运算表达式。设置好这些参数后,就可以在控制器中进行字符插值的操作了。例如,假设我们希望可以在
电子邮件的正文中进行实时编辑,当文本发生变化时进行字符插值操作并将结果展示出来。
<div ng-controller="MyController">
<input ng-model="to"
type="email"
placeholder="Recipient" />
<textarea ng-model="emailBody"></textarea>
<pre>{{ previewText }}</pre>
</div>
由于控制器内部设置了一个需要每次变化都重新进行字符插值的自定义输入字段,因此需要设置一个$watch来监听数据的变化。第23章将深入讨论$watch。为了保证示例的完整性,在这里我们为$watch引入完整的代码。
简而言之,$watch函数会监视$scope上的某个属性。只要属性发生变化就会调用对应的函数。可以使用$watch函数在$scope上某个属性发生变化时直接运行一个自定义函数。
在控制器中,我们设置了$watch来监视邮件正文的变化,并将emailBody属性的值进行字符插值后的结果赋值给previewText属性。
angular.module('myApp', [])
.controller('MyController', function($scope, $interpolate) {
// 设置监听
$scope.$watch('emailBody', function(body) {
if (body) {
var template = $interpolate(body);
$scope.previewText =
template({to: $scope.to});
}
};});
现在,在{{ previewText }}内部的文本中可以将{{ to }}当做一个变量来使用,并对文本
的变化进行实时更新。
如果需要在文本中使用不同于{{ }}的符号来标识表达式的开始和结束,可以在$inter polateProvider中配置。
用startSymbol()方法可以修改标识开始的符号。这个方法接受一个参数。 value(字符型):开始符号的值。
用endSymbol()方法可以修改标识结束的符号。这个方法也接受一个参数。 value(字符型): 结束符号的值。
如果要修改这两个符号的设置,需要在创建新模块时将$interpolateProvider注入进去。下面我们来创建一个服务,第14章会对服务进行深入讨论。
angular.module('emailParser', [])
.config(['$interpolateProvider', function($interpolateProvider) {
$interpolateProvider.startSymbol('__');
$interpolateProvider.endSymbol('__');
}])
.factory('EmailParser', ['$interpolate', function($interpolate) {// 处理解析的服务
return {
parse: function(text, context) {
var template = $interpolate(text);
return template(context);
}};
}]);
现在,我们已经创建了一个模块,可以将它注入到应用中,并在邮件正文的文本中运行这个邮件解析器:
angular.module('myApp', ['emailParser'])
.controller('MyController', ['$scope', 'EmailParser',
function($scope, EmailParser) {
// 设置监听
$scope.$watch('emailBody', function(body) {
if (body) {
$scope.previewText = EmailParser.parse(body, {
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
6.2 插值字符串 23
1
}});
}]);
to: $scope.to
});
现在用自定义的__符号取代默认语法中的{{ }}符号来请求插值文本。
由于我们将表达式开始和结束的符号都设置成了__,因此需要将HTML修改成用这个符号取代{{ }}的版本,效果如图6-1所示。
<div id="emailEditor">
<input ng-model="to"
type="email"
placeholder="Recipient" />
<textarea ng-model="emailBody"></textarea>
</div>
<div id="emailPreview">
<pre>__ previewText __</pre></div>
图6-1 插值文本