AngularJS 中的作用域隔离概念究竟是如何工作的?我的推理正确吗?

How exactly works the scope isolation concept in AngularJS? Is it my reasoning correct?

我完全是 AngularJS 的新手,我正在学习它的课程。我对展示如何使用隔离范围概念的示例有一些疑问。

所以提供的示例是一个单页应用程序,其中包含此 app.js 文件,其中包含所有应用程序逻辑:

var myApp = angular.module('myApp', ['ngRoute']);

myApp.config(function ($routeProvider) {

    $routeProvider

    .when('/', {
        templateUrl: 'pages/main.html',
        controller: 'mainController'
    })

    .when('/second', {
        templateUrl: 'pages/second.html',
        controller: 'secondController'
    })

    .when('/second/:num', {
        templateUrl: 'pages/second.html',
        controller: 'secondController'
    })

});

myApp.controller('mainController', ['$scope', '$log', function($scope, $log) {

    $scope.person = {
        name: 'John Doe',
        address: '555 Main St., New York, NY 11111'
    }

}]);

myApp.controller('secondController', ['$scope', '$log', '$routeParams', function($scope, $log, $routeParams) {



}]);


/* Declare a directive named "searchResult" */
myApp.directive("searchResult", function() {
   return {
       restrict: 'AECM',                                // This represent the ways to declare the directive into my code
       templateUrl: 'directives/searchresult.html',     // This is the template page that implement the directive
       replace: true,                                   // This specify that the directive in the main HTML code is replaced by the template code

       /* This isolate the directive scope (the model of the directive) from its parent scope (the controller that handle the page in which
        the directive is used). Because I can't directly use the person.name and the person.address property declared in the parent scope I
        specify that I use the person-name and the person-address passed as custom attribute of the search-result directive where it is used (in         the main.html)
       */
       scope: {
           personName: "@",
           personAddress: "@"
       }
   }
});

这是使用 search-result 指令的 main.html 页面:

搜索

<h3>Search Results</h3>
<div class="list-group">
    <search-result person-name="{{ person.name }}" person-address="{{ person.address }}"></search-result>
</div>

这是 searchResult.html 的代码,它是我的指令的模板:

<a href="#" class="list-group-item">
    <h4 class="list-group-item-heading">{{ personName }}</h4>
    <p class="list-group-item-text">
        {{ personAddress }}
    </p>
</a>

因此,根据我的理解(但如果我做错了断言请纠正我)范围隔离 以下列方式工作:

为了避免问题,我可以通过其父范围(例如主页的控制器)隔离子指令的范围。

要做到这一点,我只需将一个 scope JSON 对象插入指令 JavaScript 声明:

scope: {
    .............
    .............
    .............
}

但现在根据我的指令,我不能再直接访问父范围中声明的 nameaddress 属性(控制器范围)。

因此,如果我必须使用这些值,我将以这种方式声明隔离指令范围对象:

scope: {
    personName: "@",
    personAddress: "@"
}

这意味着 人名 属性 具有人名文本值 =65=] 在 search-result HTML 声明中声明(以及 personAddress 的该死的东西,事实上在我的 main.hml 文件我有

<search-result person-name="{{ person.name }}" person-address="{{ person.address }}"></search-result>

并且从这里我可以直接访问 person.nameperson.address 因为在这里我我正在使用 控制器作用域(父作用域)

所以现在在我的 JavaScript 指令中,我将这些值获取到 personNamepersonAddress 属性 中独立的子作用域对象,在我的指令模板中,我以这种方式访问​​这些属性:

<a href="#" class="list-group-item">
    <h4 class="list-group-item-heading">{{ personName }}</h4>
    <p class="list-group-item-text">
        {{ personAddress }}
    </p>
</a>

是我的推理正确还是我遗漏了什么?

这是正确的。在你的指令上使用一个独立的作用域使其可以在新的上下文中使用而不会有污染其父作用域的危险。

@属性字符串绑定 = 双向模型绑定 & 回调方法绑定

更深入地了解指令范围

enter link description here

您的理解是正确的。隔离作用域不同于普通作用域,因为它不会从原型上继承其父作用域。这在创建可重用组件时很有用,它不应该意外读取或修改父作用域中的数据,而且它也不会与父作用域强耦合。

要扩展隔离作用域的可用内容,您可以使用三个选项(来自 documentation):

@ or @attr - bind a local scope property to the value of DOM attribute. The result is always a string since DOM attributes are strings. If no attr name is specified then the attribute name is assumed to be the same as the local name. Given and widget definition of scope: { localName:'@myAttr' }, then widget scope property localName will reflect the interpolated value of hello {{name}}. As the name attribute changes so will the localName property on the widget scope. The name is read from the parent scope (not component scope).

= or =attr - set up bi-directional binding between a local scope property and the parent scope property of name defined via the value of the attr attribute. If no attr name is specified then the attribute name is assumed to be the same as the local name. Given and widget definition of scope: { localModel:'=myAttr' }, then widget scope property localModel will reflect the value of parentModel on the parent scope. Any changes to parentModel will be reflected in localModel and any changes in localModel will reflect in parentModel. If the parent scope property doesn't exist, it will throw a NON_ASSIGNABLE_MODEL_EXPRESSION exception. You can avoid this behavior using =? or =?attr in order to flag the property as optional. If you want to shallow watch for changes (i.e. $watchCollection instead of $watch) you can use =* or =attr (=? or =*?attr if the property is optional).

& or &attr - provides a way to execute an expression in the context of the parent scope. If no attr name is specified then the attribute name is assumed to be the same as the local name. Given and widget definition of scope: { localFn:'&myAttr' }, then isolate scope property localFn will point to a function wrapper for the count = count + value expression. Often it's desirable to pass data from the isolated scope via an expression to the parent scope, this can be done by passing a map of local variable names and values into the expression wrapper fn. For example, if the expression is increment(amount) then we can specify the amount value by calling the localFn as localFn({amount: 22}).

我已经解释了作用域隔离是如何工作的,并且在回答另一个问题时对应于 rootScope

如果有帮助请告诉我