首頁 web前端 js教程 AngularJS創建自訂指令的方法詳解

AngularJS創建自訂指令的方法詳解

Dec 07, 2016 pm 05:17 PM
angularjs

本文實例講述了AngularJS創建自訂指令的方法。分享給大家供大家參考,具體如下:

這是一篇譯文,來自angular開發者說明的指令。主要面向已經熟悉angular開發基礎的開發者。這篇文件解釋了什麼情況下需要創建自己的指令,和如何去創建指令。

什麼是指令

從一個高的層面來講,指令是angular $compile服務的說明,當特定的標籤(屬性,元素名,或者註釋) 出現在DOM中的時候,它讓編譯器附加指定的行為到DOM上。

這個過程是很簡單的。 angular內部有很用這樣自帶的指令,比如說ngBind, ngView,就像你創建控制器和服務一樣,你也可以創建自己的指令。當angular啟動的時候,Angular的編譯器分析html去匹配指令,這允許指令註冊行為或改變DOM。

匹配指令

在寫指令之前,我們首先需要知道的是angular是如何匹配到一個指令的,在以下的例子我們說input元素匹配到ngModel指令.

<input ng-model="foo">
登入後複製

   

下面這個方法

同樣也會匹配到ngModel:

<input data-ng:model="foo">
登入後複製

   


Angular會規範化一個元素的標籤名和屬性名,以便確定哪一個元素匹配到哪一個指令。我們在js中是透過使用規範化後的駝峰式的名字來引用指令(比如ngModel)。在HTML中常常使用'-'劃定的屬性名字來呼叫指令(比如說ng-model).

規範化的處理過程:

-去掉元素或屬性上面的x-和data-的前綴

-轉化':','-'和'_-'形式的命名為駝峰式拼字

以下例子展示了用不同的方式配對到ngBind指令

<span ng-bind="name"></span> <br/>
<span ng:bind="name"></span> <br/>
<span ng_bind="name"></span> <br/>
<span data-ng-bind="name"></span> <br/>
<span x-ng-bind="name"></span> <br/>
登入後複製

   

Best Practice: 優先使用'-'格式的命名(比如說ng-bind匹配ngBind)。如果你想在HTML驗證工具中通過,你可以用'data-'前綴的方式(例如data-ng-bind)。其他格式的命名是因為歷史遺留的原因存在,避免使用它們。

$compile服務可以基於元素的名字,屬性名,類名,和註釋來匹配指令

所有Angular內部提供的指令都匹配屬性名,標籤名,註釋,或者類名。以下不同的方式都可以被解析到

<my-dir></my-dir>
<span my-dir="exp"></span>
<!-- directive: my-dir exp -->
<span class="my-dir: exp;"></span>
登入後複製

   

Best Practice: 優先利用標籤名和屬性名的方式使用指令。這樣子更容易理解指定的元素匹配到了哪個元素。

Best Practice: 註解的方式通常被用在DOM API限制創建跨越多個元素的指令,比如說table元素,限制重複嵌套,這樣就要用註解的方式。在AngularJS 1.2版本中,透過使用ng-repeat-start 和 ng-repeat-end 作為一個更好的方案來解決這個問題。在可能的情況下,建議使用這種方式。

文字和屬性的綁定

在編譯過程中,編譯器會使用$interpolate服務來偵測符合的文字和屬性值是否包含內嵌表達式。這些表達式被註冊為watches,可以在digest循環時被更新。

<a ng-href="img/{{username}}.jpg">Hello {{username}}!</a>
登入後複製

   

ngAttr屬性的綁定

瀏覽器有些時候會對它認為合法的屬性值非常的挑剔(就是某些元素的屬性是不可以任意賦值的,否則會報錯值)。

例如:

<svg>
 <circle cx="{{cx}}"></circle>
</svg>
登入後複製

   

使用這樣的寫法時,我們會發現控制台中報錯Error: Invalid value for attribute cx="{{cx}}". OM不能簡單的寫為cx="{{cx}}".

使用ng-attr-cx 可以解決這個問題

如果一個綁定的屬性使用ngAttr前綴(或者ng-attr), 那麼在綁定的時候將會被應用到對應的未前綴化的屬性,這種方式允許你綁定到需要馬上被瀏覽器處理的屬性上面(比如SVG元素的circle[cx]屬性)。

所以,我們可以這樣寫來修復以上的問題:

<svg>
 <circle ng-attr-cx="{{cx}}"></circle>
</svg>
登入後複製

   

創建指令

首先我們來談論下註冊指令的API,跟controller一樣,指令是註冊在module上,不同的是,我們來談論下註冊指令的API,跟controller一樣,指令是註冊在module上,不同的是,指令是透過module.directive API來註冊的。 module.directive接受的是一個規範化的名字和工廠函數,這個工廠函數返回一個包含不同配置的對象,這個對像用來告訴$compile服務如何進行下一步處理。

🎜工廠函數僅在編譯器第一次匹配到指令的時候調用一次。通常在工廠函數中執行初始化的工作。函數使用$injector.invoke調用,所以它可以像controller一樣進行依賴注入。 🎜🎜Best Practice: 優先傳回一個定義好的對象,而不是回傳一個函數。 🎜🎜接下來,我們先會了解一些常見的例子,然後再深入了解不同的配置項目的原理和編譯過程。 🎜

Best Practice: 为了避免与某些未来的标准命名冲突,最好前缀化你自己的指令,比如你创建一个指令,它可能会产生冲突,加入HTML7引入相同的元素。推荐使用两三个单词的前缀(比如btfCarousel),同样不能使用ng或者其他可能与angular未来版本起冲突的前缀。

以下的例子中,我们统一使用my前缀。

模板扩展的指令

当你有大量代表客户信息的模板。这个模板在你的代码中重复了很多次,当你改变一个地方的时候,你不得不在其他地方同时改动,这时候,你就要使用指令来简化你的模板。

我们来创建一个指令,简单的时候静态模板来替换它的内容。

<div ng-controller="Ctrl">
  <div my-customer></div>
 </div>
登入後複製
登入後複製
登入後複製

JS

angular.module(&#39;docsSimpleDirective&#39;, [])
 .controller(&#39;Ctrl&#39;, function($scope) {
 $scope.customer = {
  name: &#39;Naomi&#39;,
  address: &#39;1600 Amphitheatre&#39;
 };
 })
 .directive(&#39;myCustomer&#39;, function() {
 return {
  template: &#39;Name: {{customer.name}} Address: {{customer.address}}&#39;
 };
 });
登入後複製

注意我们这里做了一些绑定,$compile编译链接

之后,它将会匹配子元素的指令。这意味着你可以组合一些指令。以下例子中你会看到如何做到这一点。

这个例子中,我们直接在template配置项里写上模板,但是随着模板大小的增加,这样非常不优雅。

Best Practice: 除非你的模板非常小,否则更好的是分割成单独的hmtl文件,然后使用templateUrl选项来加载。

假如你熟悉ngInclude,templateUrl跟它非常类似。现在我们使用templateUrl方式重写上面的例子:

<div ng-controller="Ctrl">
  <div my-customer></div>
 </div>
登入後複製
登入後複製
登入後複製

JS:

angular.module(&#39;docsTemplateUrlDirective&#39;, [])
 .controller(&#39;Ctrl&#39;, function($scope) {
 $scope.customer = {
  name: &#39;Naomi&#39;,
  address: &#39;1600 Amphitheatre&#39;
 };
 })
 .directive(&#39;myCustomer&#39;, function() {
 return {
  templateUrl: &#39;my-customer.html&#39;
 };
 });
登入後複製

my-customer.html

Name: {{customer.name}} Address: {{customer.address}}
登入後複製
登入後複製
登入後複製
登入後複製

非常好,但是如果我们想让我们的指令匹配标签名? 如果我们只是简单的把元素放在hmtl上面,会发现没有效果。

Note: 创建指令的时候,默认仅使用属性的方式。为了创建一个能由元素名字触发的指令,你需要用到restrict配置。

restrict配置可以按如下方式设置:
-'A' 仅匹配属性名字
-'E' 仅匹配元素名字
-'AE' 可以匹配到属性名字或者元素名

所以,我们可以使用 restrict: 'E'配置我们指令。

<div ng-controller="Ctrl">
  <div my-customer></div>
 </div>
登入後複製
登入後複製
登入後複製

JS

angular.module(&#39;docsTemplateUrlDirective&#39;, [])
 .controller(&#39;Ctrl&#39;, function($scope) {
 $scope.customer = {
  name: &#39;Naomi&#39;,
  address: &#39;1600 Amphitheatre&#39;
 };
 })
 .directive(&#39;myCustomer&#39;, function() {
 return {
  restrict: &#39;E&#39;,
  templateUrl: &#39;my-customer.html&#39;
 };
 });
登入後複製

my-customer.html

Name: {{customer.name}} Address: {{customer.address}}
登入後複製
登入後複製
登入後複製
登入後複製

Note: 什么时候使用属性名或元素名呢? 当创建一个含有自己模板的组件的时候,需要使用元素名,如果仅仅是为已有的元素添加功能的话,使用属性名。

使用元素名做为myCustomer指令是非常正确的决定,因为你不是用一些'customer'行为来点缀元素,而是定义一个具有自己行为的元素作为customer组件。

隔离指令的作用域

上面我们的myCustomer指令已经非常好了,但是它有个致命的缺陷,我们在给定的作用域内仅能使用一次。

它现在的实现是,我们每次重用该指令的时候都要为它新创一个控制器。

<div ng-controller="NaomiCtrl">
 <my-customer></my-customer>
</div>
<hr>
<div ng-controller="IgorCtrl">
 <my-customer></my-customer>
</div>
登入後複製

JS

angular.module(&#39;docsScopeProblemExample&#39;, [])
 .controller(&#39;NaomiCtrl&#39;, function($scope) {
 $scope.customer = {
  name: &#39;Naomi&#39;,
  address: &#39;1600 Amphitheatre&#39;
 };
 })
 .controller(&#39;IgorCtrl&#39;, function($scope) {
 $scope.customer = {
  name: &#39;Igor&#39;,
  address: &#39;123 Somewhere&#39;
 };
 })
 .directive(&#39;myCustomer&#39;, function() {
 return {
  restrict: &#39;E&#39;,
  templateUrl: &#39;my-customer.html&#39;
 };
 });
登入後複製

my-customer.html

Name: {{customer.name}} Address: {{customer.address}}
登入後複製
登入後複製
登入後複製
登入後複製

这很明显不是一个好的解决方案。

我们想要做的是能够把指令的作用域与外部的作用域隔离开来,然后映射外部的作用域到指令内部的作用域。可以通过创建isolate scope来完成这个目的。这样的话,我们使用指令的scope配置。

<div ng-controller="Ctrl">
 <my-customer customer="naomi"></my-customer>
 <hr>
 <my-customer customer="igor"></my-customer>
</div>
登入後複製

JS

angular.module(&#39;docsIsolateScopeDirective&#39;, [])
 .controller(&#39;Ctrl&#39;, function($scope) {
 $scope.naomi = { name: &#39;Naomi&#39;, address: &#39;1600 Amphitheatre&#39; };
 $scope.igor = { name: &#39;Igor&#39;, address: &#39;123 Somewhere&#39; };
 })
 .directive(&#39;myCustomer&#39;, function() {
 return {
  restrict: &#39;E&#39;,
  scope: {
  customer: &#39;=customer&#39;
  },
  templateUrl: &#39;my-customer.html&#39;
 };
 });
登入後複製

my-customer.html

Name: {{customer.name}} Address: {{customer.address}}
登入後複製
登入後複製
登入後複製
登入後複製

首先看hmtl,第一个绑定内部作用域的customer到naomi。这个naomi我们在控制器中已经定义好了。第二个是绑定customer到igor。

现在看看scope是如何配置的。

//...
scope: {
 customer: &#39;=customer&#39;
},
//...
登入後複製

属性名(customer)是myCustomer指令上isolated scope的变量名。它的值(=customer)告诉编译器绑定到customer属性。

Note: 指令作用域配置中的'=attr'属性名是被规范化过后的名字,比如要绑定

中的属性,你就要使用'=bindToThis'的绑定。

对于属性名和你想要绑定的值的名字一样,你可以使用这样的快捷语法:

//...
scope: {
 // same as &#39;=customer&#39;
 customer: &#39;=&#39;
},
//...
登入後複製

使用isolated scope还有另外一个用处,那就是可以绑定不同的数据到指令内部的作用域。

在我们的例子中,我们可以添加另外一个属性vojta到我们的作用域,然后在我们的指令模板中访问它。

<div ng-controller="Ctrl">
  <my-customer customer="naomi"></my-customer>
</div>
登入後複製

JS

angular.module(&#39;docsIsolationExample&#39;, [])
 .controller(&#39;Ctrl&#39;, function($scope) {
 $scope.naomi = { name: &#39;Naomi&#39;, address: &#39;1600 Amphitheatre&#39; };
 $scope.vojta = { name: &#39;Vojta&#39;, address: &#39;3456 Somewhere Else&#39; };
 })
 .directive(&#39;myCustomer&#39;, function() {
 return {
  restrict: &#39;E&#39;,
  scope: {
  customer: &#39;=customer&#39;
  },
  templateUrl: &#39;my-customer-plus-vojta.html&#39;
 };
 });
登入後複製

my-customer-plus-vojta.html

Name: {{customer.name}} Address: {{customer.address}}
<hr>
Name: {{vojta.name}} Address: {{vojta.address}}
登入後複製

注意到,{{vojta.name}}和{{vojta.address}}都是空的,意味着他们是undefined, 虽然我们在控制器中定义了vojta,但是在指令内部访问不到。

就像它的名字暗示的一样, 指令的isolate scope隔离了除了你添加到作用域:{}对象中的数据模型外的一切东西。这对于你要建立一个可重复使用的组件是非常有用的,因为它阻止了除了你想要传入的数据模型外其他东西改变你数据模型的状态。

Note: 正常情况下,作用域是原型继承自父作用域。但是isolate scope没有这样的继承。

Best Practice: 当你想要使你的组件在应用范围内可重用,那么使用scope配置去创建一个isolate scopes

创建一个操作DOM的指令

在这个例子中,我们会创建一个显示当前时间的指令,每秒一次更新DOM以正确的显示当前的时间。

指令修改DOM通常是在link配置中,link选项接受一个带有如下标签的函数function link(scope,element,attrs) {...}其中:

-scope是angular scope对象
-element指令匹配的jqLite封装的元素(angular内部实现的类jquery的库)
-attrs是一个带有规范化后属性名字和相应值的对象

在我们的link函数中,我们更新显示时间每秒一次,或者当用户改变指定绑定的时间格式字符串的时候。我们也要移除定时器,当指令被删除的时候,以避免引入内存泄露。

<div ng-controller="Ctrl2">
 Date format: <input ng-model="format"> <hr/>
 Current time is: <span my-current-time="format"></span>
</div>
登入後複製

JS

angular.module(&#39;docsTimeDirective&#39;, [])
 .controller(&#39;Ctrl2&#39;, function($scope) {
 $scope.format = &#39;M/d/yy h:mm:ss a&#39;;
 })
 .directive(&#39;myCurrentTime&#39;, function($timeout, dateFilter) {
 function link(scope, element, attrs) {
  var format,
   timeoutId;
  function updateTime() {
  element.text(dateFilter(new Date(), format));
  }
  scope.$watch(attrs.myCurrentTime, function(value) {
  format = value;
  updateTime();
  });
  function scheduleUpdate() {
  // save the timeoutId for canceling
  timeoutId = $timeout(function() {
   updateTime(); // update DOM
   scheduleUpdate(); // schedule the next update
  }, 1000);
  }
  element.on(&#39;$destroy&#39;, function() {
  $timeout.cancel(timeoutId);
  });
  // start the UI update process.
  scheduleUpdate();
 }
 return {
  link: link
 };
 });
登入後複製

这里有很多东西值得注意的,就像module.controller API, module.directive中函数参数是依赖注入,因此,我们可以在Link函数内部使用$timeout和dataFilter服务。

我们注册了一个事件element.on('$destroy', ...), 是什么触发了这个$destory事件呢?

AngularJS会触发一些特定的事件,当一个被angular编译过的DOM元素被移除的时候,它会触发一个$destory事件,同样的,当一个angular作用域被移除的时候,它会向下广播$destory事件到所有监听的作用域。

通过监听事件,你可以移除可能引起内存泄露的事件监听器,注册在元素和作用域上的监听器在它们被移除的时候,会自动会清理掉,但是假如注册一个事件在服务或者没有被删除的DOM节点上,你就必须手工清理,否则会有内存泄露的风险。

Best Practice:执行被移除的时候应该做一些清理的操作, 可以使用element.on('$destroy', ...)或者scope.on('$destroy', ...)来运行解除绑定的函数,

创建包裹其他元素的指令

我们现在已经实现了,使用isolate scopes传递数据模型到指令里面。但是有时候我们需要能够传递一整个模板而不是字符串或者对象。让我们通过创建'dialog box'组件来说明。这个'dialog box'组件应该能够包裹任意内容。

要实现这个,我们使用transclude配置

<div ng-controller="Ctrl">
 <my-dialog>Check out the contents, {{name}}!</my-dialog>
</div>
登入後複製
登入後複製

JS

angular.module(&#39;docsTransclusionDirective&#39;, [])
 .controller(&#39;Ctrl&#39;, function($scope) {
 $scope.name = &#39;Tobias&#39;;
 })
 .directive(&#39;myDialog&#39;, function() {
 return {
  restrict: &#39;E&#39;,
  transclude: true,
  templateUrl: &#39;my-dialog.html&#39;
 };
 });
登入後複製

my-dialog.html

<div class="alert" ng-transclude>
</div>
登入後複製
登入後複製

这个transclude配置用来干嘛呢? transclude使带有这个配置的指令的内容能够访问指令外部的作用域。

参照以下例子,注意到我们增加了一个link函数,在这个link函数内部我们重定义了name属性的值为Jeff,那么现在这个{{name}}会被解析成哪个值呢?

<div ng-controller="Ctrl">
 <my-dialog>Check out the contents, {{name}}!</my-dialog>
</div>
登入後複製
登入後複製

JS

angular.module(&#39;docsTransclusionDirective&#39;, [])
 .controller(&#39;Ctrl&#39;, function($scope) {
 $scope.name = &#39;Tobias&#39;;
 })
 .directive(&#39;myDialog&#39;, function() {
 return {
  restrict: &#39;E&#39;,
  transclude: true,
  templateUrl: &#39;my-dialog.html&#39;,
  link: function (element, scope) {
  scope.name = &#39;Jeff&#39;;
  }
 };
 });
登入後複製

my-dialog.html

<div class="alert" ng-transclude>
</div>
登入後複製
登入後複製

一般,我们会认为{{name}}会被解析为Jeff,然而这里,我们看到这个例子中的{{name}}还是被解析成了Tobias.

transclude配置改变了指令相互嵌套的方式,他使指令的内容拥有任何指令外部的作用域,而不是内部的作用域。为了实现这个,它给指令内容一次访问外部作用域的机会。

这样的行为对于包裹内容的指令是非常有意义的。因为如果不这样的话,你就必须分别传入每个你需要使用的数据模型。如果你需要传入每个要使用的数据模型,那么你就无法做到适应各种不同内容的情况。

Best Practice: 仅当你要创建一个包裹任意内容的指令的时候使用transclude:true。

下一步,我们增加一个按钮到'dialog box'组件里面,允许用户使用指令绑定自己定义的行为。

<div ng-controller="Ctrl">
  <my-dialog ng-hide="dialogIsHidden" on-close="dialogIsHidden = true">
  Check out the contents, {{name}}!
  </my-dialog>
</div>
登入後複製

JS

angular.module(&#39;docsIsoFnBindExample&#39;, [])
 .controller(&#39;Ctrl&#39;, function($scope, $timeout) {
 $scope.name = &#39;Tobias&#39;;
 $scope.hideDialog = function () {
  $scope.dialogIsHidden = true;
  $timeout(function () {
  $scope.dialogIsHidden = false;
  }, 2000);
 };
 })
 .directive(&#39;myDialog&#39;, function() {
 return {
  restrict: &#39;E&#39;,
  transclude: true,
  scope: {
  &#39;close&#39;: &#39;&onClose&#39;
  },
  templateUrl: &#39;my-dialog-close.html&#39;
 };
 });
登入後複製

my-dialog-close.html

<div class="alert">
 <a href class="close" ng-click="close()">×</a>
 <div ng-transclude></div>
</div>
登入後複製

我们想要通过在指令的作用域上调用,来运行我们传递进去的函数,但是这个函数是运行在定义时候的上下文(js通常都是这样子的)。

先前我们看到如何scope配置使用'=prop',但是在上文的例子中,我们使用'&prop','&'绑定开放了一个函数到isolated scope,允许 isolated scope调用它,同时维持原来函数的作用域(这里的作用域都是指$scope)。所以当一个用户点击x时候,就会运行Ctrl控制器的close函数。

Best Practice: 当你的指令想要开放一个API去绑定特定的行为,在scope配置中使用'&prop'.

创建一个添加事件监听器的指令

先前,我们使用link函数创建一个操作DOM元素的指令,基于上面的例子,我们创建一个在元素上添加事件监听的指令。

举个例子,假如我们想要创建一个让用户可拖拽的元素,该怎么做呢?

Drag ME

JS

angular.module(&#39;dragModule&#39;, []).
 directive(&#39;myDraggable&#39;, function($document) {
 return function(scope, element, attr) {
  var startX = 0, startY = 0, x = 0, y = 0;
  element.css({
  position: &#39;relative&#39;,
  border: &#39;1px solid red&#39;,
  backgroundColor: &#39;lightgrey&#39;,
  cursor: &#39;pointer&#39;
  });
  element.on(&#39;mousedown&#39;, function(event) {
  // Prevent default dragging of selected content
  event.preventDefault();
  startX = event.screenX - x;
  startY = event.screenY - y;
  $document.on(&#39;mousemove&#39;, mousemove);
  $document.on(&#39;mouseup&#39;, mouseup);
  });
  function mousemove(event) {
  y = event.screenY - startY;
  x = event.screenX - startX;
  element.css({
   top: y + &#39;px&#39;,
   left: x + &#39;px&#39;
  });
  }
  function mouseup() {
  $document.unbind(&#39;mousemove&#39;, mousemove);
  $document.unbind(&#39;mouseup&#39;, mouseup);
  }
 }
 });
登入後複製

创建相互通信的指令

你可以通过在模板使用指令来组合任何指令。

有时候,你想要一个指令从其他的指令上面创建

想象你想要一个带有tab的容器,容器的内容对应于激活的tab。

<my-tabs>
  <my-pane title="Hello">
  <h5 id="creating-custom-directives_source_hello">Hello</h5>
  <p>Lorem ipsum dolor sit amet</p>
  </my-pane>
  <my-pane title="World">
  <h5 id="creating-custom-directives_source_world">World</h5>
  <em>Mauris elementum elementum enim at suscipit.</em>
  <p><a href ng-click="i = i + 1">counter: {{i || 0}}</a></p>
  </my-pane>
</my-tabs>
登入後複製

JS

angular.module(&#39;docsTabsExample&#39;, [])
 .directive(&#39;myTabs&#39;, function() {
 return {
  restrict: &#39;E&#39;,
  transclude: true,
  scope: {},
  controller: function($scope) {
  var panes = $scope.panes = [];
  $scope.select = function(pane) {
   angular.forEach(panes, function(pane) {
   pane.selected = false;
   });
   pane.selected = true;
  };
  this.addPane = function(pane) {
   if (panes.length == 0) {
   $scope.select(pane);
   }
   panes.push(pane);
  };
  },
  templateUrl: &#39;my-tabs.html&#39;
 };
 })
 .directive(&#39;myPane&#39;, function() {
 return {
  require: &#39;^myTabs&#39;,
  restrict: &#39;E&#39;,
  transclude: true,
  scope: {
  title: &#39;@&#39;
  },
  link: function(scope, element, attrs, tabsCtrl) {
  tabsCtrl.addPane(scope);
  },
  templateUrl: &#39;my-pane.html&#39;
 };
 });
登入後複製

my-tabs.html

<div class="tabbable">
 <ul class="nav nav-tabs">
 <li ng-repeat="pane in panes" ng-class="{active:pane.selected}">
  <a href="" ng-click="select(pane)">{{pane.title}}</a>
 </li>
 </ul>
 <div class="tab-content" ng-transclude></div>
</div>
登入後複製

my-pane.html

<div class="tab-pane" ng-show="selected" ng-transclude>
</div>
登入後複製

   

myPane指令有一个require:'^myTabs'的配置,当指令使用这个配置,$compile服务叫myTabs的指令并获取它的控制器实例,如果没有找到,将会抛出一个错误。'^'前缀意味着指令在它的父元素上面搜索控制器(没有'^'前缀的话,指令默认会在自身的元素上面搜索指定的指令)。

这里myTabs的控制器是来自何处呢?通过使用controller配置可以为指令指定一个控制器, 上问例子中myTab就是使用这个配置。就像ngController, 这个配置为指令的模板绑定了一个控制器。

再看我们的myPane's定义,注意到link函数的最后一个参数: tabCtrl,当一个指令包含另一个指令(通过require方式),它会接收该指令的控制器实例作为link函数的第四个参数,利用这个,myPane可以调用myTabs的addPane函数。

精明的读者可能想知道link跟controller之间的区别,最基本的区别就是控制器开放一个API(就是这个控制器实例可以被其他实例读取到),link函数可以通过require与控制器交互。

Best Practice: 当你要开放一个API给其他指令的时候使用控制器,否则使用link函数。

总结

这里我们讲解了一个些指令的主要使用案例。每一个都可以作为你创建自己指令的很好的起点。

如果你想更深入的了解编译的处理过程,可以查看compiler guide相关内容

$compile API页面有directive每个配置项的具体解释,可以参阅。

希望本文所述对大家AngularJS程序设计有所帮助。


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1424
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
2022年最新5款的angularjs教學從入門到精通 2022年最新5款的angularjs教學從入門到精通 Jun 15, 2017 pm 05:50 PM

Javascript 是一個非常有個性的語言. 無論是從程式碼的組織, 還是程式碼的程式設計範式, 或物件導向理論都獨具一格. 而很早就在爭論的Javascript 是不是物件導向語言這個問題, 顯然已有答案. 但是, 即使Javascript 叱吒風雲二十年, 如果想要看懂jQuery, Angularjs, 甚至是React 等流行框架, 觀看《黑馬雲課堂JavaScript 高級框架設計視頻教程》就對了。

使用PHP和AngularJS建立響應式網站,提供優質的使用者體驗 使用PHP和AngularJS建立響應式網站,提供優質的使用者體驗 Jun 27, 2023 pm 07:37 PM

在現今資訊時代,網站已成為人們獲取資訊和交流的重要工具。一個響應式的網站能夠適應各種設備,為使用者提供優質的體驗,成為了現代網站開發的熱點。本篇文章將介紹如何使用PHP和AngularJS建立響應式網站,進而提供優質的使用者體驗。 PHP介紹PHP是一種開源的伺服器端程式語言,非常適合Web開發。 PHP具有許多優點,如易於學習、跨平台、豐富的工具庫、開發效

使用PHP和AngularJS建立Web應用 使用PHP和AngularJS建立Web應用 May 27, 2023 pm 08:10 PM

隨著網路的不斷發展,Web應用已成為企業資訊化建設的重要組成部分,也是現代化工作的必要手段。為了讓Web應用能夠方便開發、維護和擴展,開發人員需要選擇適合自己開發需求的技術框架和程式語言。 PHP和AngularJS是兩種非常流行的Web開發技術,它們分別是伺服器端和客戶端的解決方案,透過結合使用可以大大提高Web應用的開發效率和使用體驗。 PHP的優勢PHP

使用Flask和AngularJS建立單頁Web應用程式 使用Flask和AngularJS建立單頁Web應用程式 Jun 17, 2023 am 08:49 AM

隨著Web技術的快速發展,單頁Web應用程式(SinglePageApplication,SPA)已成為越來越流行的Web應用程式模型。相較於傳統的多頁Web應用程序,SPA的最大優勢在於使用者感受更加流暢,同時伺服器端的運算壓力也大幅減少。在本文中,我們將介紹如何使用Flask和AngularJS來建構一個簡單的SPA。 Flask是一款輕量級的Py

AngularJS基礎入門介紹 AngularJS基礎入門介紹 Apr 21, 2018 am 10:37 AM

這篇文章介紹的內容是關於AngularJS基礎入門介紹,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下。

如何使用PHP和AngularJS進行前端開發 如何使用PHP和AngularJS進行前端開發 May 11, 2023 pm 05:18 PM

隨著網路的普及和發展,前端開發已變得越來越重要。身為前端開發人員,我們需要了解並掌握各種開發工具和技術。其中,PHP和AngularJS是兩種非常有用且受歡迎的工具。在本文中,我們將介紹如何使用這兩種工具進行前端開發。一、PHP介紹PHP是一種流行的開源伺服器端腳本語言,它適用於Web開發,可以在Web伺服器和各種作業系統上運作。 PHP的優點是簡單、快速、便

如何在PHP編程中使用AngularJS? 如何在PHP編程中使用AngularJS? Jun 12, 2023 am 09:40 AM

隨著Web應用程式的普及,前端框架AngularJS變得越來越受歡迎。 AngularJS是一個由Google開發的JavaScript框架,它可以幫助你建立具有動態Web應用程式功能的網頁應用程式。另一方面,對於後端編程,PHP是非常受歡迎的程式語言。如果您正在使用PHP進行伺服器端編程,那麼結合AngularJS使用PHP將可以為您的網站帶來更多的動態效

使用PHP和AngularJS開發一個線上文件管理平台,方便文件管理 使用PHP和AngularJS開發一個線上文件管理平台,方便文件管理 Jun 27, 2023 pm 01:34 PM

隨著網路的普及,越來越多的人使用網路進行檔案傳輸和分享。然而,由於各種原因,使用傳統的FTP等方式進行檔案管理無法滿足現代使用者的需求。因此,建立一個易用、高效、安全的線上文件管理平台已成為了一種趨勢。本文介紹的線上文件管理平台,基於PHP和AngularJS,能夠方便地進行文件上傳、下載、編輯、刪除等操作,並且提供了一系列強大的功能,例如文件共享、搜尋、

See all articles