Jer*_*Jer 0 angularjs angularjs-directive angularjs-controller
我是AngularJS的相对入门者,正在编写一个具有各种可重用组件的应用程序(例如,同一张表可能在屏幕上出现5次,但列数略有不同-如有必要,我可以详细介绍)。其他人也会想编写使用这些组件的代码。同样,多个组件将要从相同的来源中提取数据,并且多个人将要进行相同的REST调用以获取数据。
我想到的一般架构:
举一个简单的例子,一条指令将使用ng-repeat打印一个名称列表。服务将具有一个“公共”函数getNames(),该函数返回名称列表。我正在编写一个应用程序-我使用“ canned”指令和服务,我编写了一个将服务作为依赖项的控制器,调用getNames()函数并将结果返回到指令。我的HTML页面像其他任何HTML元素一样简单地使用指令。
我的主要问题-将数据放入指令的最佳方法是什么?我知道就范围而言,有很多选择,但是必须在我的控件中创建一个具有特定名称的变量并“神奇地”工作似乎是错误的。
从广义上讲,这是否合理?我基本上将指令和服务视为开发人员将使用的公共API。
听起来您正在寻找的就是所谓的隔离范围。在指令内部定义了隔离范围,并且在视图中使用指令时,隔离范围中的变量被分配为属性。
例如,考虑以下指令:
myApp.directive('myTable', function () {
return {
restrict: 'E',
replace: true,
templateUrl: 'MyTable.html',
scope: {
foo: '=items'
}
};
});
Run Code Online (Sandbox Code Playgroud)
该指令具有两个属性。在这里,我将只讨论scope属性,但是您可以在这里阅读其余内容(以及一般的指令)。
scope属性定义隔离范围。隔离作用域使您可以映射外部控制器作用域的值,从而可以绑定到它们,而不必担心外部作用域中实际存在的内容。这是一个抽象层,可让您的指令更加灵活和可重用。
scope对象中的每个属性都定义了隔离范围内的某些内部属性与某些外部控制器的范围对象之间的映射。在上面的示例中,我们有一个名为的属性foo。属性定义的右侧(称为"=items")正在声明变量映射。这实际上是在说:“在实例化此指令时,请在html元素上查找名为“ items”的属性,并将其值分配给隔离范围内名为“ foo”的属性。
因此,例如,如果我们指令的模板(由上面的templateUrl属性指定)如下:
// MyTable.html
<table style="width:300px">
<tr>
<td ng-repeat="item in foo">{{item}}</td>
</tr>
</table>
Run Code Online (Sandbox Code Playgroud)
然后,我们可以在我们的主要html页面中使用此指令,如下所示:
<div ng-controller="SomeGenericController">
<my-table items="ourItems" />
</div>
Run Code Online (Sandbox Code Playgroud)
请注意,上面已将items属性添加到指令中,并为其分配了值ourItems。现在,这里有一个澄清;分配时items="ourItems",我们必须在控制器的作用域上具有一些名为的属性ourItems。因此,例如,也许我们的控制器如下所示:
myApp.controller('SomeGenericController', ['$scope', function ($scope) {
$scope.ourItems = ['ball', 'shovel', 'towel'];
});
Run Code Online (Sandbox Code Playgroud)
上面的用法将显示一个表格,其中包含SomeGenericController的items数组中的项目。
使用此模式,我们可以分配任何旧数组来使用此表指令。假设我们还有其他一些控制器,这些控制器具有一系列要放入表中的项目:
myApp.controller('AccountsController', ['$scope', function ($scope) {
$scope.names = ['john', 'jill', 'ted'];
...
// some more stuff down here specific to this controller
});
Run Code Online (Sandbox Code Playgroud)
现在,我们可以通过使用属性将names数组映射到隔离作用域的foo属性,从而将table指令与此控制器一起使用items:
<div ng-controller="AccountsController">
<my-table items="names" />
</div>
Run Code Online (Sandbox Code Playgroud)
因此,这就是创建可重用指令的基本思路。我们可以使用一些技巧来使此清洁器更清洁。例如,如果属性映射的名称和isolate scope属性的名称相同,则可以使用简写=代替=items。在定义映射时,还可以使用其他一些运算符,即@和&,但我会让您自己查看它们:)您还可以定义内部包含在指令定义中并在指令定义中指定的控制器,这又是我会留给您一些东西以了解更多信息:)
无论如何,希望这会有所帮助!