javascript - 控制器能做哪些指令不能做的事情?
问题描述
我刚开始使用AngularJS。当我第一次开始阅读它时,从初学者教程看来,控制器是 Angular 应用程序的基本构建块。然而,自从学习指令以来,我一直在创建自己的小 Angular 应用程序,只有指令,实际上不是一个控制器。我不明白为什么我需要一个控制器。
我见过的唯一使用控制器完成的事情就是将变量添加到范围:
angular.controller("myController",
function($scope)
{
$scope.x = 5;
$scope.y = 6;
}
)
但是我也可以使用指令来做到这一点,方法是使用scope
传递给链接函数的参数。
有没有其他可以用控制器完成的事情,而不能用指令完成?或者至少是控制器比指令更容易做的事情?
例如,如果我只需要用一些变量x
an填充范围y
,我可以这样做:
angular.directive(
"myDirective",
function()
{
return {
link: function(scope, element, attributes)
{
scope.x = 5;
scope.y = 6;
}
};
}
);
解决方案
link
当然,您可能可以在回调中编写应用程序所需的几乎所有内容。请注意,我什至没有将其称为指令,我说的是link
回调。指令是定义自定义 HTML 标记及其相关功能的东西,link
回调只是其中的特定部分。
问题是,这只不过是使用 jQuery,或者addEventListener
用于将行为附加到 HTML 元素。另一方面,您可以将控制器编写为类,而不是操作scope
对象的过程代码。这是我在typescript中编写angularjs的首选风格:
export default class WidgetController {
error: string;
static $inject = ['$state', 'FooService', 'BarService'];
constructor(
protected $state: angular.ui.IStateService,
protected foo: FooService,
protected bar: BarService
) {}
get fooValue() {
return this.foo.baz;
}
doSomething() {
this.error = null;
this.bar.getSomething().then(data => {
if (data.error) {
this.error = data.error;
} else {
this.$state.go('success');
}
});
}
}
用于此的模板可能如下所示:
<h1>{{ $ctrl.fooValue }}</h1>
<button ng-click="$ctrl.doSomething()">Do!</button>
<p>{{ $ctrl.error }}</p>
控制器可以使用 ui-router 附加到模板:
import WidgetController from 'widget-controller';
module.config(['$stateProvider', ($state: angular.ui.IStateProvider) => {
$state.state('widget', {
controller: WidgetController,
controllerAs: '$ctrl',
templateUrl: '/templates/widget.html',
});
}]);
或作为一个组件:
module.component('widget', {
templateUrl: '/templates/widget.html',
controller: WidgetController,
bindings: {
error: '@'
}
});
或使用ng-controller
或以许多其他方式。
它为您提供更大的灵活性。它允许您非常轻松地单独测试控制器,因为它只是一个常规类。它允许您为不同的模板重用控制器,并为不同的控制器重用相同的模板(是的,这实际上非常有用)。它的 IMO 更具可读性和更易于理解。在模板中特别使用$ctrl.
可防止您构建过于相互依赖的嵌套范围,并显式绑定模板以仅使用其控制器,而不是某些隐式范围。
有很多方法可以做事,但随着时间的推移我发现一件事是处理scope
对象既冗长又烦人,并且很容易导致意大利面条式代码。因此,远离这一点,您很快就会将控制器作为对象。
推荐阅读
- python - 检测何时加载新页面
- c++ - 错误 C2760:语法错误:意外标记 '<',预期为 ';'
- wordpress - 使用来自子主题而不是来自父主题的 JS 文件
- python - Scikit-learn 入门
- apache - 如果一个页面无法加载或真的很慢,你不能同时在同一个网站上打开另一个页面:为什么?
- rest - 仅使用 POST 符合 RESTful
- python - 当 yaxis 整数改变长度时,matplotlib plot_dates 换行
- javascript - Javascript - 忽略 Switch 语句中的标点符号和空格
- java - 如何将实体管理器查询中的无类型列表转换为类型列表?
- python - 在 django 中找不到静态文件