[angular] 篇 指令中的scope

scope參數有如下幾種方式:javascript

  1,不填,默認爲scope:falsehtml

  2,scope:truejava

  3,scope:{}函數

  4,spa

scope:{

    name: '=',

    age: '@',

    say: '&'    

   }

下面我來分別說明他們之間的用法:code

  第一種:看代碼htm

<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),這時指令中的做用域便是其父級所處的做用域,這裏能夠調用到父級做用中的變量和方法;對象

如:blog

<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>

相關文章
相關標籤/搜索