2014-01-05 79 views
5

我是Angular的新手,並試圖理解高級指令API - 我想使用指令元素屬性在編譯函數中重新創建指令模板。 但是,當我沒有模板集(或模板是空字符串),而是訪問孤立的指令範圍,我訪問父(控制器)範圍。此外 - 這工作對角1.1而不是1.2指令與模板之間的區別與沒有模板和Angular 1.2和1.1之間的區別?

這裏是HTML:

<div class="container" ng-app="app" ng-controller="AppController"> 
     <sandbox title="Attribute Title"></sandbox> 
</div> 

的JavaScript:

var app = angular.module('app', [], function() {}); 

app.controller('AppController', function ($scope) { 
    $scope.title = "AppController title"; 
}); 

app.directive('sandbox', function ($log, $compile) { 
    return { 
     restrict: 'E', 
     scope: { 
      title: "@" 
     }, 
     controller: function ($scope, $element, $attrs) { 
      $scope.title = "Directive Controller title"; 
     }, 
     template: '<h1>Template</h1>', // change it to: '' and Run, than change Angular to 1.2.x 
     compile: function (tElement, tAttrs) { 
      tElement.append('<h2> Title = {{ title }}</h2>'); 
     } 
    } 

}); 

當你運行它,你得到:

模板

Title = Att ribute標題

但是,當您更改模板,您角1.2得到空字符串:

標題= AppController的標題

而且隨着角度1.1.1:

標題=屬性標題

我的問題:

爲什麼在設置模板和未設置模板時訪問範圍存在差異? (bug? - 沒有'template'的指令和isoleted範圍是否包含控制器範圍而不是指令範圍)?爲什麼在Angular 1.1和1.2之間存在差異?

如何在編譯函數中構建訪問獨立範圍的模板而不是在Angular 1.2中的父範圍?

爲什麼指令控制器函數不會使用$ scope.title =「...」更改'title',但是當調試'link'函數'title'中的'scope'參數值是'Directive Controler Title'但它內部(在哪裏尋找它)綁定isoleted作用域'屬性值'?

這裏的jsfiddle播放使用:http://jsfiddle.net/yoorek/zQ66L/4/

回答

7

你打,在1.2發生了很大的變化(在使用怪癖「@」)。

1)當你的模板是Angular的時候,沒有模板去應用隔離範圍。這是1.2中問題的原因在於對第二個問題的回答。

2)這是此結果1。2中斷變更 - make isolate scope truly isolate

隔離範圍現在僅適用於請求它及其模板的隔離指令。

因此,如果沒有模板,您將追加到隔離範圍外的元素。
https://github.com/angular/angular.js/issues/4889

正如我們無法區分的標記,這是最初出現在在編譯功能加入後者也 沒有得到分離範圍的HTML文件 和標記。

...在編譯功能附加標記應使用 模板屬性所取代。
這個想法是模板屬性也可以是一個函數。如果它是 是1,它將得到編譯元素和編譯屬性爲 參數。

3)正如你看到的上面,角(後1.2)確實在努力推你要使用的模板,而不是這裏的編譯功能。你最好的選擇是使用你正在使用編譯方式的模板函數。或者,您可以使用鏈接功能與$compile - 但這可能會增加不必要的複雜性。

通過追加編譯功能,您實際上只是添加到模板中,所以它是解決這個問題的方法。

4)這與@的工作方式有關。從Angulars guide to scopes

使用ATTRS $觀察鏈接 功能(「attr_name」,函數(值){...}來獲取使用「@」符號分離作用域屬性 的插值。例如,如果我們在鏈接 函數 - attrs。$ observe('interpolated',函數(值){...} - 值將被設置爲11.(scope.interpolatedProp未定義在 鏈接函數。相反,scope.twowayBindingProp定義在 的鏈接函數中,因爲它使用'='符號。)

你也可能會讀這個SO post on the difference between @ and =

+0

很好的答案,但#4一段時間以來都不是真的。我認爲從1.1.x開始,「@」將在鏈接函數的作用域中定義。看到這個例子:http://plnkr.co/edit/IVfc7P1a9Kj4RQTrp7Dx?p=preview – dtabuenc

+0

@dtabuenc看看這個更新的plnkr:http://plnkr.co/edit/fH452EsTPjEJNJV0L6Xa所以我認爲使用示波器版本仍然有風險(取決於繼承) - 但我很樂意錯誤。 – KayakDave

+0

鏈接函數中$ scope的使用沒有問題,它在控制器中的用法不正確。 「@」綁定是單向的,因此永遠不會寫入。寫入它的任何值都將在下一個摘要循環中被覆蓋。 – dtabuenc

相關問題