javascript - AngularJS 中的范围隔离概念究竟是如何工作的?我的推理正确吗?

标签 javascript angularjs angularjs-directive angularjs-scope javascript-framework

我绝对是 AngularJS 的新手,我正在学习它的类(class)。我对展示如何使用隔离范围概念的示例有一些疑问。

因此,所提供的示例是一个包含此 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 指令的 ma​​in.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>

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

为避免出现问题,我可以通过其父范围(例如主页的 Controller )来隔 ionic 指令的范围。

为此,我只需将一个 scope JSON 对象插入到指令 JavaScript 声明中:

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

但现在根据我的指令,我无法再直接访问在父范围( Controller 范围)中声明的 nameaddress 属性。

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

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

这意味着 personName 属性具有 search-result 中声明的 person-name文本值 strong> HTML 声明(以及 personAddress 的该死的东西,事实上在我的 ma​​in.hml 文件中

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

从这里我可以直接访问 person.nameperson.address 因为我在这里使用的是 controller scope (父范围)

现在,在我的 JavaScript 指令中,我将这些值获取到隔 ionic 范围对象的 personNamepersonAddress 属性中,并在我的指令模板中访问这些属性,这样:

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

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

最佳答案

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

要扩展隔离作用域的可用内容,您可以使用三个选项(来自 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}).

关于javascript - AngularJS 中的范围隔离概念究竟是如何工作的?我的推理正确吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33723075/

相关文章:

PHP/JS : Echoing several variables without losing their value

javascript - 在 javascript 中读取 iFrame 中 div 的状态(不在同一域 - YouTube)

javascript - Angularjs检查数组中是否存在传递值

javascript - AngularJS : $scope. $监视一个对象并仅返回其更改的属性

AngularJS $watch 在第一次更新后数组失败

javascript - 在 Node.JS 中使用 HTTP 读取文件

javascript - 带有 jscodeshift 的 Codemod - 从导入中删除逗号

javascript - 我们在哪里可以找到 TextAngular 的 textarea 元素

javascript - Angular2 不遍历模型数组

angularjs - 将 ng-class 与条件一起使用时,类指令不起作用