[angular] 篇 指令中的scope

scope参数有以下几种方式:

  1,不填,默认为scope:false

  2,scope:true

  3,scope:{}

  4,

scope:{

    name: ‘=‘,

    age: ‘@‘,

    say: ‘&‘    

   }

下面我来分别说明他们之间的用法:

  第一种:看代码

<script>
    angular module(‘exampleApp‘, [])
        .controller(‘scopeCtrl‘, function ($scope) {
          // do something
         });
        .directive(‘scopeDome‘, function () {
             return {
                 template:
                     "<div class=‘body‘>Name:<input ng-model=‘name‘></div>"
             }
         })
</script>

这里没有对scope做定义,则angular会调用默认值(scope:false),这时指令中的作用域即是其父级所处的作用域,这里可以调用到父级作用中的变量和方法;

如:

<script type="text/javascript">
        angular.module("exampleApp", [])
            .directive("scopeDemo", function () {
                return {
                    template: function() {
                        return angular.element(
                            document.querySelector("#scopeTemplate")).html();
                    },
                    link: function (scope, element, attrs) {
                        scope.func(); // 调用父级控制器里的方法;
                    }
                }
            })
        .controller("scopeCtrl", function ($scope) {
            $scope.data = { name: "Adam" };
            $scope.city = "London";
            $scope.func = function () {
                alert(‘you can call me!‘);
            }
        });
    </script>

  第二种:看代码

js部分:

<script type="text/ng-template" id="scopeTemplate">
    <div class="panel-body">
        <p>Name: <input ng-model="data.name" /></p>
        <p>City: <input ng-model="city" /></p>
        <p>Country: <input ng-model="country" /></p>
    </div>
</script>
<script type="text/javascript">
    angular.module("exampleApp", [])
        .directive("scopeDemo", function () {
            return {
                    template: function() {
                        return angular.element(
                            document.querySelector("#scopeTemplate")).html();
                    },
                    scope: true,
                    link: function (scope, element, attrs) {
                        scope.func();
                    }
                }
            })
        .controller("scopeCtrl", function ($scope) {
            $scope.data = { name: "Adam" };
            $scope.city = "London";
            $scope.func = function () {
                alert(‘ok‘);
            }
        });</script>

HTML部分

<body ng-controller="scopeCtrl">
    <div class="panel panel-default">
        <div class="panel-body" scope-demo></div>
        <div class="panel-body" scope-demo></div>
    </div>
</body>

在HTML中有两处调用了这个指令,但生产的效果是不太一样的,在运行时

效果是,Name是同步的(上下改变任何一个另一个都会跟着变),City和Country却是独立的,上下两个改变都不会影响到另外一个;

原因是scope:true允许我们在同一个控制器中创造一个新作用域,但这个作用域是可以继承其父级的作用域的属性和方法的,那么是不是跟没写scope一样了,其实不然,因为他毕竟创造了自己的作用域,那么他的自由性就会比没写scope强,那么为什么有的能动态一起变,有的不能呢,那就看看他们的数据属性吧:

<div class="panel-body">
    <p>Name: <input ng-model="data.name" /></p>
    <p>City: <input ng-model="city" /></p>
    <p>Country: <input ng-model="country" /></p>
</div>在控制器中:
.controller("scopeCtrl", function ($scope) {
            $scope.data = { name: "Adam" };
            $scope.city = "London";
            $scope.func = function () {
                alert(‘ok‘);
            }
        });
名称 描述
data.name 这个属性是在一个对象上定义的,意味着这个值将会在指令中的各个实例之间共享,而且所有绑定到该属性的输入框元素将会保持同步
city 这个属性是在控制器的作用域上直接被赋值的,意味着指令所有的作用域将会从同一个初始值开始,但是在输入框元素被修改时会在自己的作用域上创建和修改自己的版本
country 这个属性没有被赋任何值,当相应的输入框元素被修改时, 指令的每个实例将会创建出独立的county属性。

  第三种:看代码

<script type="text/javascript">
        angular.module("exampleApp", [])
            .directive("scopeDemo", function () {
                return {
                    template: function() {
                        return angular.element(
                            document.querySelector("#scopeTemplate")).html();
                    },
                    scope: {}
                }
            })
        .controller("scopeCtrl", function ($scope) {
            $scope.data = { name: "Adam" }; // 这两个方法将不能传到指令中,供指令使用
            $scope.city = "London";
        });
    </script>

scope:{} 表示告诉angular这个指令要创建一个独立(隔离)的作用域,这样这个独立的作用域就不能继承外界的父级控制器的作用域。这样的好处是指令在复用时不会污染到外界的父级作用域。

  第四种

第四种是第三种方式的强化,即虽然我的作用域与外界隔离了,但有一些参数(数值,属性,方法)还是想从外界获得。那么该如何获得呢,

angular提供了三种方法供我们使用,分别是 ‘=’、 ‘@’、 ‘&’, 他们的作用分别是:

  @: 通过属性值进行绑定,但是单向的,即外界控制器可以把值传进来供内部使用,但内部对这个属性值进行修改时不会影响到外部的;

  js部分

<script type="text/ng-template" id="scopeTemplate">
        <div class="panel-body">
            <p>Data Value: {{local}}</p>
        </div>
    </script>
    <script type="text/javascript">
        angular.module("exampleApp", [])
            .directive("scopeDemo", function () {
                return {
                    template: function() {
                        return angular.element(
                            document.querySelector("#scopeTemplate")).html();
                    },
                    scope: {
                        local: "@nameprop"
                    }
                }
            })
        .controller("scopeCtrl", function ($scope) {
            $scope.data = { name: "Adam" };
        });
    </script>

HTML部分

<body ng-controller="scopeCtrl">
    <div class="panel panel-default">
        <div class="panel-body">
            Direct Binding: <input ng-model="data.name" /> // 这里改变下面会跟着改变
        </div>
        <div class="panel-body" scope-demo nameprop="{{data.name}}"></div> // 跟着上面数值动态变化
    </div>
</body>

指令中的local通过nameprop获得外部属性data.name,所以在控制器中的data.name变化时,指令中的local也会跟着改变;(但如果是只改变local的值,外界的data.name是不会变的);

  =: 通过属性进行双向数据绑定,内外变化会保持一致;

js部分

<script type="text/ng-template" id="scopeTemplate">
        <div class="panel-body">
            <p>Data Value: <input ng-model="local" /></p>
        </div>
    </script>
    <script type="text/javascript">
        angular.module("exampleApp", [])
            .directive("scopeDemo", function () {
                return {
                    template: function() {
                        return angular.element(
                            document.querySelector("#scopeTemplate")).html();
                    },
                    scope: {
                        local: "=nameprop"
                    }
                }
            })
        .controller("scopeCtrl", function ($scope) {
            $scope.data = { name: "Adam" };
        });
    </script>

HTML部分

<body ng-controller="scopeCtrl">
    <div class="panel panel-default">
        <div class="panel-body">
            Direct Binding: <input ng-model="data.name" />
        </div>
        <div class="panel-body" scope-demo nameprop="data.name"></div>
    </div>
</body>

显示的效果:

指令和控制器双方通过 local: "=nameprop" 进行双向数据绑定;

  &: 调用父级作用域中的方法(function);

js部分

<script type="text/ng-template" id="scopeTemplate">
        <div class="panel-body">
            <p>Name: {{local}}, City: {{cityFn()}}</p>
        </div>
    </script>
    <script type="text/javascript">
        angular.module("exampleApp", [])
            .directive("scopeDemo", function () {
                return {
                    template: function () {
                        return angular.element(
                            document.querySelector("#scopeTemplate")).html();
                    },
                    scope: {
                        local: "=nameprop",
                        cityFn: "&city"
                    }
                }
            })
        .controller("scopeCtrl", function ($scope) {
            $scope.data = {
                name: "Adam",
                defaultCity: "London"
            };
            $scope.getCity = function (name) {
                return name == "Adam" ? $scope.data.defaultCity : "Unknown";
            }
        });
    </script>

HTML部分

<body ng-controller="scopeCtrl">
    <div class="panel panel-default">
        <div class="panel-body">
            Direct Binding: <input ng-model="data.name" />
        </div>
        <div class="panel-body" scope-demo
             city="getCity(data.name)" nameprop="data.name"></div>
    </div>
</body>

city特性的值是一个表达式,调用了getCity行为并将data.name属性作为参数传入进行处理。要使这个表达式在隔离作用域中可用,在scope中添加 cityFn: "&city",前缀‘&’就告诉angular,我想将所指定特性的值(cityFn)绑定到一个函数,剩下就是在指令中调用这个函数表达式了:{{cityFn()}}

PS:这里所有指令作用域跟外界交互都是通过属性值传入的:<div class="panel-body" scope-demo city="getCity(data.name)" nameprop="data.name"></div>

时间: 2024-12-27 08:45:31

[angular] 篇 指令中的scope的相关文章

Angular 从DOM中获取scope

节选官方文档: 原文:https://docs.angularjs.org/guide/scope Retrieving Scopes from the DOM. Scopes are attached to the DOM as $scope data property, and can be retrieved for debugging purposes. (It is unlikely that one would need to retrieve scopes in this way

angular js 指令的数据传递 及作用域数据绑定

<div my-directive my-url="http://google.com" my-link-text="Click me to go to Google"></div> angular.module('myApp', []) .directive('myDirective', function() { return { restrict: 'A', replace: true, scope: { myUrl: '@', //绑定

angular指令中使用ngModelController

在这篇文章中 angular学习笔记(三十)-指令(10)-require和controller 说到了通过require属性和controller参数来让指令与指令之间互相交互. 本篇主要介绍的是指令与ngModel指令的交互.也就是说,ngModel指令虽然是内置的,但它也有自己的controller属性,其它指令也可以通过require来得到ngModel指令的controller属性的实例来与ngModel指令进行交互. ngModelController用在什么场合呢?我们知道,ngM

Angular 中得 scope 作用域梳理

$scope 的使用贯穿整个 Angular App 应用,它与数据模型相关联,同时也是表达式执行的上下文.有了 $scope 就在视图和控制器之间建立了一个通道,基于作用域视图在修改数据时会立刻更新 $scope,同样的 $scope 发生改变时也会立刻重新渲染视图. 有了 $scope 这样一个桥梁,应用的业务代码可以都在 controller 中,而数据都存放在controller 的 $scope 中. $rootScope Angular 应用启动并生成视图时,会将根 ng-app 元

angular js权威指南笔记三--向指令中传递数据

给指令添加属性,这个属性会成为指令内部作用域的属性 有好几种途径可以设置指令内部作用域中属性的值.最简单的方法就是使用由所属控制器提供的已经存在的作用域. 但是会导致很多其他问题.如果控制器被移除,或者在控制器的作用域中也定义了一个叫 相同的属性名,我们就被迫要修改代码 AngularJS 允许通过创建新的子作用域或者隔离作用域来解决这个常见问题 <div my-directive some-property="someProperty with @ binding">&l

Angular中directive——scope选项与绑定策略,这个也经常迷惑的。

开门见山地说,scope:{}使指令与外界隔离开来,使其模板(template)处于non-inheriting(无继承)的状态,当然除非你在其中使用了transclude嵌入,这点之后的笔记会再详细记录的.但是这显然不符合实际开发中的需求,因为实际上,我们经常想要我们的指令能够在特定的情况下与外界进行数据上的交互,这就需要借助绑定策略之手了. 大家知道,当scope选项写为scope:{}这种形式的时候,就已经为指令生成了隔离作用域,现在,我们来看看绑定策略的三种形式:& .= .@. 首先是

angular中的scope

angular.element($0).scope() 什么是scope? scope是一个refer to the application model的object.它是一个expression的执行上下文context.scopes模仿DOM的层次模型也有层次关系.Scopes可以watch一个expression也可以propagate events. scope特性 scope提供API $watch来观察模型的变化 scope提供API $apply来传播angular外部世界(比如c

在angular的自定义回调中操作$scope

在angular的controller中有时候会使用到自定义的回调, 比如异步请求的回调函数 一般返回之后都需要更新页面的数据,即更新$scope.xx 但是如果直接 $scope.xx = data.info 这样根本不会有任何的影响 解决方案 this.callback = function (status) { $scope.$apply(function () { $scope.xx = status; }); }; Scope提供$watch方法监视Model的变化. Scope提供$

AngularJS指令中的compile与link函数解析

AngularJS指令中的compile与link函数解析 通常大家在使用ng中的指令的时候,用的链接函数最多的是link属性,下面这篇文章将告诉大家complie,pre-link,post-link的用法与区别. 原文地址 angularjs里的指令非常神奇,允许你创建非常语义化以及高度重用的组件,可以理解为web components的先驱者. 网上已经有很多介绍怎么使用指令的文章以及相关书籍,相互比较的话,很少有介绍compile与link的区别,更别说pre-link与post-lin