为啥我应该在 AngularJS 中使用隔离范围指令?

Posted

技术标签:

【中文标题】为啥我应该在 AngularJS 中使用隔离范围指令?【英文标题】:Why i should use isolated scope directives in AngularJS?为什么我应该在 AngularJS 中使用隔离范围指令? 【发布时间】:2015-09-02 13:08:12 【问题描述】:

我想知道为什么我应该使用隔离范围指令?我总是可以在我的控制器内通过服务获取一些数据,这些数据将在没有隔离范围的指令中可用,如果我想在其他地方使用该指令,我可以发送请求并获取数据...... 。 正确的?

当您创建具有隔离范围的指令时,您必须获取数据并将其传递给指令..

使用隔离作用域指令有什么好处?

我为什么要使用它以及何时使用它?*

【问题讨论】:

【参考方案1】:

因为它使您的指令成为一个自己的模块(设计方面,我不是在谈论 angular.modules ;-) 具有明确定义的自包含接口,这意味着它可以在任何上下文中重用。它还使其代码可读,因为该指令使用的所有内容都在指令代码中,而不是在它所依赖的某个神奇的父范围内。让我们看一个没有独立作用域的示例:

控制器:

angular.module("carShop",[])
.controller("CarStorefrontController",function()
    //For simplicity
    this.cars = [
         name: 'BMW X6', color: 'white' ,
         name: 'Audi A6', color: 'black'  
    ];
);

指令:

angular.module("carShop")
.directive("carList",function()
    return 
        template: ['<ul>',
                       '<li ng-repeat="car in vm.cars">',
                       'A car.name in shiny-car.color',
                       '</li>',
                   '</ul>'].join("")
    ;
);

页面:

<div ng-app="carShop" ng-controller="CarStorefrontController as vm">
    <h2>Welcome to AwesomeCarShop Ltd. !</h2>
    <p>Have a look at our currently offered cars:</p>
    <car-list></car-list>
</div>

这可行,但不可重复使用。如果我想在我的应用程序的其他地方显示汽车列表,我需要将我的控制器重命名为vm,并让它有一个名为cars 的字段,其中包含我的汽车数组以使其工作。但是,如果我将指令更改为

angular.module("carShop")
.directive("carList",function()
    return 
        scope:  cars: '=' ,
        template: [ /* same as above */ ].join("")
    ;
);

并将我店面页面上的&lt;car-list&gt;&lt;/car-list&gt; 更改为&lt;car-list cars="vm.cars"&gt;&lt;/car-list&gt;",我可以在任何地方重复使用该指令,只需传入任何汽车数组,而无需关心该数组的来源。此外,我现在可以用一个完全不同的控制器替换店面页面上的控制器,而无需更改我的指令定义(并且无需更改我使用汽车列表的所有其他位置)。

这实际上归结为为什么您不应该将所有 javascript 变量放在一个全局范围内以便从任何地方都可以轻松访问它们的相同原因:可重用性、可读性、可维护性 - 这就是您通过模块化和 encapsulating 您的代码,通过在black-box-principle 后面输入low coupling and high cohesion。

【讨论】:

另外,关于孤立作用域的解释也差不多:onehungrymind.com/angularjs-sticky-notes-pt-2-isolated-scope很好的答案! @VeskoVujovic 如果你说得更清楚一点,添加一些 short 代码示例并提供references 我很乐意这样做:-)【参考方案2】:

当您想要创建一个可在整个应用程序中重用的组件时,基本上使用具有隔离范围的指令,以便您可以在 Angular 模块的任何位置使用它。

独立作用域意味着您正在创建一个新作用域,该作用域在原型上不会从父作用域继承。但是您可以将值传递给您希望从父范围要求的指令。它们可以通过属性值以各种形式传递,您可以选择使用scope: 将指令作为隔离范围。

    @ - 表示像 somevalue 这样的插值 = - 表示与中提到的父范围变量的两种方式绑定 属性somevalue &amp; - 表示您可以将方法引用传递给可以从指令调用的指令

使用$scope.$new(true); 创建的隔离范围,其中$scope 是放置指令标记的当前范围。

正如您所说,您要将数据存储在 Service 中,而不是创建一个孤立的范围。但是这种方法永远不会为您工作,因为服务是只有一个实例的单例事物。如果您想多次使用您的指令,那么您需要在服务中创建另一个变量,该变量将获取其他元素所需的数据。如果那个指令数增加到 10,那么想想你的服务会是什么样子,那看起来真的很可怜。

通过使用隔离作用域,代码看起来更加模块化,代码可重用性将得到提高。独立作用域变量永远不会与父作用域中同名的其他变量发生冲突。

【讨论】:

以上是关于为啥我应该在 AngularJS 中使用隔离范围指令?的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS自定义验证指令 - 如何避免使用隔离范围

AngularJS指令隔离范围和父范围

AngularJS中带有ng-repeat范围的指令隔离范围

如何在 AngularJS 中对隔离范围指令进行单元测试

为啥我应该在 AngularJS 中选择使用服务而不是工厂? [复制]

在 AngularJS 中隔离作用域回退