【发布时间】:2015-07-28 00:27:08
【问题描述】:
我正在尝试将编写 AngularJS 应用程序的方式从纯 JavaScript 更改为使用 TypeScript 作为预处理器。
当涉及到作用域方法调用时,我正在努力协调这两种方法。
出于说明目的,让我们考虑常见的菜单用例;我希望突出显示当前显示的特定菜单项。 HTML 模板如下所示:
<ul class="nav navbar-nav">
...
<li ng-class="{active: isSelected('/page1')}"><a href="#/page1">Page 1</a></li>
...
</ul>
这需要一个名为isSelected 的作用域函数。使用老式 javascript 编码,我将其写为:
$scope.isSelected = function(path) {
return $location.path().substr(0, path.length) == path;
}
这个匿名函数声明似乎并不真正尊重更传统的 TypeScript 类模型。在打字稿中,我发现自己很想写这个:
export interface MenuScope extends ng.IScope {
isSelected(path: String): boolean;
}
export class MenuController {
location: ng.ILocationService;
scope: MenuScope;
constructor($scope: MenuScope, $location: ng.ILocationService) {
this.scope = $scope;
this.location = $location;
this.scope.isSelected = function(path) { return this.isSelected(path) }.bind(this);
}
isSelected(path: String): boolean {
return this.location.path().substr(0, path.length) == path;
}
}
在这种情况下,isSelected 属于控制器,而不是作用域。这似乎是明智的。但是,作用域和控制器之间的“链接”仍然依赖于匿名方法。
更糟糕的是,我不得不显式绑定this 的上下文,以确保我可以编写this.location 来访问isSelected() 实现中的定位服务。
我从 TypeScript 中寻找的好处之一是更清晰的代码编写方式。这种通过绑定匿名函数进行的间接访问似乎与 this 正好相反。
【问题讨论】:
-
使用“Controller as vm”sintax 并且可以工作,那么你应该调用 vm.isSelected
标签: javascript angularjs typescript