Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Angular JS:指令&x2019;当我们已经有指令’;有范围的控制器?_Javascript_Angularjs_Angularjs Directive - Fatal编程技术网

Javascript Angular JS:指令&x2019;当我们已经有指令’;有范围的控制器?

Javascript Angular JS:指令&x2019;当我们已经有指令’;有范围的控制器?,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我需要对范围和模板执行一些操作。似乎我可以在链接功能或控制器功能中这样做(因为两者都可以访问范围) 什么时候我必须使用链接功能而不是控制器 angular.module('myApp').directive('abc', function($timeout) { return { restrict: 'EA', replace: true, transclude: true, scope: true, lin

我需要对范围和模板执行一些操作。似乎我可以在
链接
功能或
控制器
功能中这样做(因为两者都可以访问范围)

什么时候我必须使用
链接
功能而不是控制器

angular.module('myApp').directive('abc', function($timeout) {
    return {
        restrict: 'EA',
        replace: true,
        transclude: true,
        scope: true,
        link: function(scope, elem, attr) { /* link function */ },
        controller: function($scope, $element) { /* controller function */ }
    };
}
另外,我知道
link
是一个无角度的世界。因此,我可以使用
$watch
$digest
$apply

当我们已经有控制器时,
链接
功能的意义是什么?

为什么需要控制器
angular.module('myApp').directive('abc', function($timeout) {
    return {
        restrict: 'EA',
        replace: true,
        transclude: true,
        scope: true,
        link: function(scope, elem, attr) { /* link function */ },
        controller: function($scope, $element) { /* controller function */ }
    };
}
当您希望在DOM中嵌套指令并将父指令中的API函数公开给嵌套指令时,
link
controller
之间的区别就开始发挥作用

从:

最佳实践:当您想向其他指令公开API时,请使用controller。否则请使用链接

假设您希望有两个指令
我的表单
我的文本输入
,并且您希望
我的文本输入
指令只出现在
我的表单
中,而不出现在其他任何地方

在这种情况下,在定义指令
my text input
时,您会说它需要一个来自
parent
DOM元素的控制器,使用require参数,如下所示:
require:'^myForm'
。现在,父元素的控制器将作为第四个参数
$scope,element,attributes
之后的
注入
链接
函数中。您可以在该控制器上调用函数并与父指令通信

此外,如果找不到这样的控制器,则会引发错误

为什么要使用链接 如果正在定义
控制器
,则实际上不需要使用
链接
功能,因为
控制器
上有
$scope
。此外,在定义
链接
控制器
时,确实需要注意两者的调用顺序(
控制器
之前执行)


然而,与角度方式一致,大多数使用
$watchers
的DOM操作和双向绑定通常在
链接
函数中完成,而用于子对象和
$scope
操作的API则在
控制器
中完成。这不是一条硬性规定,但这样做将使代码更加模块化,并有助于分离关注点(控制器将保持
指令
状态,
链接
函数将保持
DOM
+外部绑定).

控制器
函数/对象表示抽象模型-视图-控制器(MVC)。虽然MVC并没有什么新鲜的东西可写,但它仍然是angular最显著的优势:将关注点分割成更小的部分。仅此而已,如果您需要对来自
视图的
模型
更改做出反应,
控制器
就是做这项工作的合适人选

关于
link
函数的故事是不同的,它来自不同的视角,然后是MVC。一旦我们想要跨越
控制器/模型/视图
(模板)的边界,这是非常重要的

让我们从传递到
链接中的参数开始:

function link(scope, element, attrs) {
  • 范围是一个角度范围对象
  • 元素是此指令匹配的jqLite包装元素
  • attrs是一个具有规范化属性名称及其对应值的对象
要将
链接
放到上下文中,我们应该提到所有指令都要经过这个初始化过程步骤:编译、链接。摘自Brad Green和Shyam Seshadri的书:

编译阶段(link的姐妹,让我们在这里提及它以获得清晰的图片):

在此阶段,Angular遍历DOM以识别所有已注册的 模板中的指令。对于每个指令,它将转换 基于指令规则的DOM(模板、替换、转包和 依此类推),并调用编译函数(如果存在)。结果是一场灾难 编译模板函数

链接阶段

要使视图成为动态视图,请为每个视图运行链接函数 指令。链接函数通常在DOM上创建侦听器 或者模型。这些侦听器使视图和模型保持同步 一直都是

在这里可以找到如何使用
链接的一个很好的示例:。请参见示例:创建一个指令来操作DOM,该指令在页面中插入一个“日期-时间”,每秒钟刷新一次

只是上面rich源代码中的一个很短的片段,展示了DOM的真正操作。有一个钩住$timeout服务的函数,它在析构函数调用中被清除,以避免内存泄漏

.directive('myCurrentTime', function($timeout, dateFilter) {

 function link(scope, element, attrs) {

 ...

 // the not MVC job must be done
 function updateTime() {
   element.text(dateFilter(new Date(), format)); // here we are manipulating the DOM
 }

 function scheduleUpdate() {
   // save the timeoutId for canceling
   timeoutId = $timeout(function() {
     updateTime(); // update DOM
     scheduleUpdate(); // schedule the next update
   }, 1000);
 }

 element.on('$destroy', function() {
   $timeout.cancel(timeoutId);
 });

 ...

在我的初始
链接
控制器
函数斗争并阅读了大量有关它们的内容后,我想现在我找到了答案

首先让理解

简而言之,角度指令是如何工作的:

  • 我们从模板开始(作为字符串或加载到字符串)

    var templateString='{{5+10}}'

  • 现在,这个
    templateString
    被包装成一个角度元素

    var el=angular.element(templateString)

  • 使用
    el
    ,现在我们使用
    $compile
    编译它,以返回链接函数

    var l=$compile(el)

    下面是发生的情况

    • $compile