2012-12-24 135 views
11

控制範圍這是我的應用程序配置:無法訪問的指令

angular.module('myApp', ['myApp.directives', 'myApp.controllers', 'myApp.services']); 

這是我的控制器:

angular.module('myApp.controllers', []) 
    .controller('MainCtrl', function ($scope) { 
     $scope.name = 'world'; 
    }); 

這是我的指令:

var directives = angular.module('myApp.directives', []); 

directives.directive("hello", function() { 
    return function (scope, elm, attrs) { 
     elm.text("hello, " + scope[attrs.name]); 
    }; 
}); 

這是我的html:

<div ng-controller="MainCtrl"> 
    <h1 hello></h1> 
</div> 

的是問題是,角渲染指令爲:

你好,不確定

相反的:

你好,世界

什麼是錯的?

回答

7

您正在訪問scope[attrs.name]但該指令不提供該屬性的值name

有2個選項:

  1. 更改指令elm.text("hello, " + scope['name']); 這不是首選方式它硬編碼到示波器屬性名稱

  2. 將html更改爲<h1 hello name="name"></h1>。這是更好,但我覺得它採用了冗餘的屬性

我建議你改變指令elm.text("hello, " + scope[attrs['hello']]);

甚至更​​好elm.text("hello, " + scope.$eval(attrs['hello']));

這樣你得到的表達式的利益以及(例如:<h1 hello="name|uppercase"></h1>demo

這樣的HTML是<h1 hello="name"></h1>

關於attrs參數:它只不過是從dom元素上存在的屬性取得的字符串映射。

+0

這是行不通的。我仍然沒有定義。 – vcardillo

+0

@vcardillo以及添加plunker或提出問題:) –

+0

調試後,我意識到我的問題是我在我的指令定義對象中使用'scope:{...}'屬性,從而創建一個新的隔離範圍。我正在阻止原型繼承。 – vcardillo

3

您可以使用scope訪問。看http://jsfiddle.net/rPUM5/

directives.directive("hello", function() { 
    return function (scope, elm, attrs) { 
     elm.text("hello, " + scope.name); 
    }; 
});​ 
+0

這真的很有趣,謝謝!我已經發現關於使用點語法的文檔很少。 – vcardillo

+3

這真的是錯誤的,傳遞給鏈接函數的'scope'對象與控制器實例化的'$ scope'不一樣,它是對實例化該指令的範圍的只讀引用,應該用'scope' 。 – fiatjaf

+1

誰說這是一樣的?你不可能通過編寫$ scope來訪問$ scope。這只是違反了公約。放置$ before範圍並不意味着它是控制器的範圍對象。 – Mahbub

6

你可以做一些,寫這篇文章,出現在角是無證(見馬克Rajcok的評論在這裏:http://docs.angularjs.org/api/ng.$rootScope.Scope)。

從你的指令中:

scope.$parent.name 

如果你對指令的scope(從指令中),你會看到這些特性console.log(scope)

所有這一切說,我不知道這是否是「正確的」Angular約定,由於這是既沒有記錄,也沒有找到任何其他更好的文檔關於如何訪問控制器該指令位於內部。

1

我找到了另一種情況:

,如果你正在訪問來自Ajax請求的身體來了一個變量,那麼你必須等到變量設置

e.g:

# in controller 
$http.get('/preview').then((response) -> 
    $scope.tabs = response.data.tabs 
    $scope.master_switch = '1' 
    console.info 'after get response in controller' 
) 

# in directive 
directive('masterSwitch', -> 
    (scope, element, attrs) -> 
    alert 'in directive!' # will show before "after get response in controller" 
    console.info scope.master_switch # is undefined 
    setTimeout(-> console.info(scope.master_switch), 50) # => 1