2017-05-05 118 views
0

在angularjs指令的指導教程中,指令對象可以具有scope屬性。它定義了指令的範圍。如何理解angularjs中指令的作用域屬性?

雖然範圍屬性附加傷害值可能是真實的,遵循的是範圍:(link of the scope definition解釋)

true: A new child scope that prototypically inherits from its parent will be created for the directive's element. If multiple directives on the same element request a new scope, only one new scope is created.

我感到這是在大膽風格的句子感到困惑。同一元素上的多個指令如何使用相同的範圍?

回答

1

據我說,這意味着範圍將創建每個元素,而不是每個指令。

因此,範圍將自動在指令之間共享,而不會爲每個指令創建不同的副本。

在這裏,在這個環節https://www.bennadel.com/blog/2729-don-t-blindly-isolate-all-the-scopes-in-angularjs-directives.htm

他們都提到:

如果您使用AngularJS 1.2,接下來的障礙是,你不能將兩個分離範圍的指令適用於同一元素。看看下面的代碼。它所做的就是將兩個指令應用於相同的元素。而且,這些指令只需要一個隔離範圍。

因此,如果您在這兩個指令使用相同的範圍變量,然後它會引發以下錯誤

Error: error:multidir

Multiple Directive Resource Contention

Multiple directives [bnThat, bnThis] asking for new/isolated scope on

因此,對於這樣的情況,transclusion或放置指令在嵌套的方式可以做的工作。

上面提到的例子在下面的代碼片段中給出。

// Create an application module for our demo. 
 
var app = angular.module("Demo", []); 
 
// -------------------------------------------------- // 
 
// -------------------------------------------------- // 
 
// I request an isolate scope directive. 
 
app.directive(
 
    "bnThis", 
 
    function() { 
 
    // Return the directive configuration. Notice that we are creating an 
 
    // isolate scope, even though we are not binding any expressions. 
 
    return ({ 
 
     link: angular.noop, 
 
     restrict: "A", 
 
     scope: {} 
 
    }); 
 
    } 
 
); 
 
// -------------------------------------------------- // 
 
// -------------------------------------------------- // 
 
// I request an isolate scope directive. 
 
app.directive(
 
    "bnThat", 
 
    function() { 
 
    // Return the directive configuration. Notice that we are creating an 
 
    // isolate scope, even though we are not binding any expressions. 
 
    return ({ 
 
     link: angular.noop, 
 
     restrict: "A", 
 
     scope: {} 
 
    }); 
 
    } 
 
);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 

 
<div ng-app="Demo"> 
 

 
    <p bn-this bn-that> 
 
    Look at the console output. 
 
    </p> 
 

 
</div>

1

我們不知道是什麼範圍將包含在使用我們的指令點。 因此,爲我們的指令提供一個定義明確的公開 界面接口是一個好習慣。這可以確保該指令不能依賴於其使用的範圍上的任意屬性,也不會受其影響。 我們有三個選項用於我們的指令及其模板中使用的範圍。 在指令定義中定義:
•從使用小部件的位置重用範圍。這是默認的 ,對應於範圍:false。

•創建一個子範圍,它從使用該控件的範圍中原型繼承。你可以使用scope來指定它:true。

•創建一個不原型繼承的隔離範圍,以便它與其父項完全隔離。您可以通過將對象傳遞給 scope屬性來指定此範圍:scope:{...}。 我們希望將我們的小部件模板與 應用程序的其餘部分完全分離,以便在兩者之間沒有數據泄漏的危險。

注: - [在一個孤立的範圍不prototypically從其父, 繼承它仍然可以通過$ parent屬性訪問其父的範圍。 但是,這是因爲你破壞了 脫離其周圍的指令被認爲是不好的做法。]

由於我們的範圍現在是從父範圍隔離,我們需要父範圍之間明確地映射 值孤立的範圍。這是通過在指令出現的元素的屬性上引用 AngularJS表達式來完成的。 對於我們的分頁指令,num-pages和當前頁面屬性履行此角色。 我們可以通過手錶將這些屬性中的表達式與 模板範圍內的屬性同步。我們可以手動設置它,或者我們可以要求 AngularJS爲我們進行連線。有三種類型的接口,我們可以在元素的屬性和隔離範圍之間指定 :interpolate(@),data bind(=)和表達式(&)。您可以在指令定義的範圍屬性中將這些接口指定爲鍵值對。 關鍵是隔離範圍上的字段的名稱。值@ =之一,或& 接着元件上的屬性的名稱:

scope: { 
isolated1: '@attribute1', 
isolated2: '=attribute2', 
isolated3: '&attribute3' 
} 

在這裏,我們已經定義了對所述分離的範圍的三個字段和AngularJS人員 值從指定映射指令出現的元素上的屬性。

注: [如果屬性名稱是從值被省略,則假定 該屬性具有相同的名稱作爲所述分離的範圍字段: 範圍:{isolated1:「@」} 它將期望的屬性被稱爲isolated1。]

插值與@屬性 的@符號指示AngularJS應該內插指定 屬性的值,並更新所述分離的範圍屬性時它的變化。插值是 與{{}}花括號一起使用來使用父作用域中的值生成字符串。 注意: - [一個常見的錯誤是期望內插對象本身是對象 。插值始終返回一個字符串。因此,如果您有一個對象,比如說 用戶有一個名爲userName的字段,則{{user}} 的插值會將用戶對象轉換爲字符串,並且您將無法 訪問字符串上的userName屬性。 ]

該屬性內插相當於手動$觀察屬性:

attrs.$observe('attribute1', function(value) { 
isolatedScope.isolated1 = value; 
}); 

ATTRS $$觀察員[ 'ATTRIBUTE1'] $$範圍= parentScope; 使用= 將數據綁定到該屬性=符號表示AngularJS應該將表達式保留在指定的 屬性中,並且隔離範圍上的值彼此同步。這是一個雙向 數據綁定,它允許直接在內部 和控件外部映射對象和值。 由於此接口支持雙向數據綁定,屬性中給出的表達式 應該是可分配的(即,指的是 作用域或對象上的字段),而不是任意的計算表達式。 這種結合是一個有點像設置了兩個$手錶功能:

var parentGet = $parse(attrs['attribute2']); 
var parentSet = parentGet.assign; 
parentScope.$watch(parentGet, function(value) { 
isolatedScope.isolated2 = value; 
}); 
isolatedScope.$watch('isolated2', function(value) { 
parentSet(parentScope, value); 
}); 

實際的實現更復雜,以確保兩個範圍的穩定性。 提供回調錶達在 屬性與& 的&符號表示在屬性設置在元件 上的表達將提供的範圍,因爲,調用它時,將執行表達式 的函數。這對於從窗口小部件創建回調很有用。 建立自己的指令 這種結合相當於$解析屬性中的表達和暴露在隔離範圍 解析表達式功能:

parentGet = $parse(attrs['attribute3']); 
scope.isolated3 = function(locals) { 
    return parentGet(parentScope, locals); 
}; 
相關問題