了解角度控制器Vs指令

时间:2015-08-17 13:37:04

标签: javascript angularjs

我对angularjs很新。我试图理解为什么使用这个指令比使用控制器更好。两个示例都输出相同的值。

指令示例:

angular.module('docsSimpleDirective', [])
.controller('Controller', ['$scope', function($scope) {
  $scope.customer = {
    name: 'Naomi',
    address: '1600 Amphitheatre'
  };
}])
.directive('myCustomer', function() {
  return {
    template: 'Name: {{customer.name}} Address: {{customer.address}}'
  };
});

标记:

<div ng-controller="Controller">
  <div my-customer></div>
</div>

控制器示例:

angular.module('docsSimpleDirective', [])
    .controller('Controller', ['$scope', function($scope) {
      $scope.customer = {
        name: 'Naomi',
        address: '1600 Amphitheatre'
      };
    }])

标记:

<div ng-controller="Controller">
   Name: {{customer.name}} Address: {{customer.address}}     
 </div>

也许我只是不完全理解指令。

4 个答案:

答案 0 :(得分:5)

在工作中,我们使用简单的练习来查看是否需要指令。 如果某个代码段被多次使用,我们会将其转换为指令。

指令还有机会为模板添加更少的混乱。

angular.module('DocsSimpleDirective', [])
    .controller('DocsController', [function() {
        this.customer = {
            name: 'Naomi',
            address: '1600 Amphitheatre'
        };
    }])
    .directive('myCustomer', function() {
        return {
            scope: true
            restrict: 'EA',
            controller: 'DocsController',
            controllerAs: 'docsCtrls',
            templateUrl: 'assets/template/my-customer.directive.html'
        };
    })
;

允许将您的模板定义为:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Angular test</title>
</head>
<body ng-app="DocsSimpleDirective">
    <my-customer></my-customer>
</body>
</html>

和你的指令:

<article>
    <strong>{{ docsCtrls.customer.name }}</strong><br>
    {{ docsCtrls.customer.address }}
</article>

就个人而言,我试图避免使用$scope来绑定数据。如果其他人开始阅读你的代码,那么在某个控制器上的某个控制器中定义的神奇customer比某个控制器上的变量更难识别。

隔离$ scope可能很有用(通过定义scope: true)来使用默认值。如果你需要停止隔离你的指令,它应该是你想到的,而不是因为它是默认值 如果不隔离范围,它将继承$parentScope中定义的所有值,这在嵌套指令时非常有用,其中所有指令都应该知道它们来自哪个父级。这有一个非常明显的危险,您可以操纵不应被操纵的parentcope中的数据。

https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope

答案 1 :(得分:2)

您需要设置scope:true

的其他事项
.directive('myCustomer', function() {
  return {
    scope:true,
    template: 'Name: {{customer.name}} Address: {{customer.address}}'
  };
});

REFER THIS DOC

答案 2 :(得分:2)

如何将功能绑定到模板有多种可能的方法,有些方法比其他方法更好。

  1. BAD - 直接在ng-controller模板中使用html属性 绑定控制器功能

  2. 更好 - 使用ngRouteui-router指定路线/状态或您的应用程序,您可以在每个路线/州指定controllertemplate

  3. BEST - 使用directive definiton对象,您可以再次指定controllertemplate将它们绑定在一起,然后在模板和路径中使用指令。
  4. 第三个示例非常灵活,您可以在任何其他模板(如<div my-directive></div>)中使用指令,也可以在任何路由器中使用指针作为内联模板,例如:template: '<div my-directive></div>'

    第三种方法是最好的,因为它是朝向未来组件的方向(因为React,Angular 2.0和Webcomponents)。我写了一个blog post并创建了一个示例github repository来说明这些概念。

答案 3 :(得分:1)

<强>控制器:

控制器用于增强角度范围。

当Controller通过ng-controller指令附加到DOM时,Angular将使用指定的Controller的构造函数实例化新的Controller对象

控制器用于:

  1. 设置$ scope对象的初始状态。

  2. 向$ scope对象添加行为。

  3. 不要使用控制器:

    1. 操纵DOM - 控制器应仅包含业务逻辑。

    2. 格式输入 - 改为使用角度形式控件。

    3. 滤镜输出 - 改为使用角度滤镜。

    4. 跨控制器共享代码或状态 - 改为使用角度服务。

    5. <强>指令:

      在高级别,指令是DOM元素上的标记(例如属性,元素名称,注释或CSS类),它告诉AngularJS的HTML编译器($ compile)将指定的行为附加到该DOM元素甚至转换DOM元素及其子元素。

      Angular内置了一组这些指令,如ngBind,ngModel和ngClass。

      您可以为Angular创建自己的指令。

      通常指令用于:

      1. 注入或包装现有物品。
      2. 在不同的地方重复使用相同的东西
      3. 可以在DOM元素中注入属性,元素,注释或类
      4. 所以如果你需要在不同的地方重用相同的dom或逻辑,那么你应该使用指令而不是控制器。

        您还可以从内部指令

        访问父控制器对象

        像:

        <div data-ng-controller="mainController">
           <p>hello world</p>
           <some-directive></some-directive> // inject directive as element
        </div>