2014-03-02 96 views
2

我創建了一個指令來理解轉換和隔離範圍。 下面是HTML:AngularJs指令轉換錯誤和@綁定

<div ng-app="myApp"> 
    <div ng-controller="MyCtrl"> 
     <div> 
      <input type="text" ng-model="name" /> 
      <input type="number" ng-model="friendCount" /> 
     </div> 
     <my-friends name="{{name}}"> 
      <p>Hi, I'm {{name}}, and I have {{friendCount}} friends</p> 
     </my-friends> 
    </div> 
</div> 

指令:

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

app.controller('MyCtrl', function ($scope) { 
    $scope.name = "John Doe"; 
    $scope.friendCount = 3; 
}); 

app.directive('myFriends', function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     template: '<div>' + 
      ' <h3> Isolated Scope: {{name}}</h3>' + 
      ' <div ng-transclude></div>' + 
      '</div>', 
     transclude: true, 
     scope: { 
      name: '@' 
     }, 
     link: function (scope, element, attrs) { 
      scope.name = "Anderson"; 
     } 
    } 
}); 

打開此琴:JsFiddle

我有兩個問題:

  1. 爲什麼{{名} }在指令模板中說「John Doe」而不是「Anderson」?我期望它是Anderson,因爲name屬性是原型繼承的,並且一旦在鏈接函數中寫入它,就會失去祖先連接。

  2. 它似乎是transcluding正確,但它爲什麼會拋出錯誤錯誤:[ngTransclude:orphan]在開發工具控制檯?它可能是我使用的角度版本?

任何幫助,非常感謝。

這裏是小提琴:JsFiddle

UPDATE:

的transclusion誤差是由於誤加載角的兩倍。

使用@綁定時,您可以在初始摘要循環完成後覆蓋name裏面的指令,例如在點擊處理程序中。但是,只要更改父範圍的名稱屬性,它就會被覆蓋。

關於@綁定的問題是我對孤立範圍的誤解。它正在按照它在示例中應有的方式工作。 隔離範圍不會從父項原型繼承。而且綁定的含義也被稱爲只讀訪問或單向綁定,它不會讓你更新/寫入父範圍。

修訂FIDDLE

回答

1

1)隨着@結合,在消化階段,角將重新評估表達式,並設置值返回到控制器的電流值,這將覆蓋值中的鏈接功能設置。

2)你有2個版本的角裝載小提琴。第二次加載的角度再次遍歷DOM,並嘗試再次編譯已編譯的DOM的。欲瞭解更多信息,看看我回答另一個問題Illegal use of ngTransclude directive in the template

DEMO

+0

謝謝Khanh。很好的接收。我刪除了角度的第二個引用後,transclusion錯誤消失了。但是,使用@綁定,即使最初將name屬性綁定到控制器,我也應該可以在指令鏈接函數中覆蓋它,而無需修改父級/控制器範圍,對吧? – Harish

+0

@Harish:實際上,你可以覆蓋鏈接函數中的值。但是,循環結束時,角度更新綁定時,angular會評估你的表達式('{{name}}')並重寫你的作用域的屬性。要解決這個問題,請嘗試'='綁定 –

1

的AngularJS文檔是在不斷變化的這樣的狀態,我無法找到相關的不同類型的隔離範圍綁定的網頁,所以我對任何不準確之處表示歉意。

How to make it work

scope: { 
    name: '=' //formerly @ 
}, 

IIRC的@綁定將傳過來的字符串文字的值。我不肯定爲什麼這意味着鏈接函數分配不會覆蓋它,如果我能找到文檔中的部分,然後我鏈接到它。

=綁定綁定到範圍屬性的值,並在更新時更新隔離範圍和分配範圍。

<my-friends name="name"> //formerly name="{{name}}" 

使用一個範圍屬性需要傳遞而不是字符串值的=結合的裝置。

再次,對於任何不正確或模糊的信息抱歉。如果我能找到dang文檔,我會更新答案。

+0

這個問題可能是相關的「爲」與「等於」:http://stackoverflow.com/questions/14050195/what即指示範圍內的差異 –

+0

感謝您的回覆。我特別試圖驗證單向綁定,所以我用@。但{{name}}似乎與控制器綁定,而不是指令,這對我來說是造成混亂的原因。 – Harish

+0

drew_w的鏈接比我能在這裏更好地解釋差異。基本上,單向綁定會阻止您將其分配給鏈接函數中的屬性。 – bmceldowney