2014-01-23 93 views
1

伴隨plunker(在CoffeeScript中,但低於的JavaScript)AngularJs指令 - 屬性範圍的變量不具約束力

我不能讓一個屬性範圍的變量(@)在一個指令綁定。

這裏的指令代碼:

app.directive('myDirective', [ 
    function() { 

    var compileFn, config, linkFn; 

    linkFn = function($scope, element, attr) { 
     return alert("foo: " + $scope.foo); 
    }; 

    compileFn = function() { 
     return linkFn; 
    }; 

    return config = { 
     compile: compileFn, 
     scope: { 
     foo: '@myDirectiveFoo' 
     } 
    }; 
    } 
]); 

和HTML:

<span my-directive my-directive-foo="bar"></span> 

我期望驚動真實將「酒吧」的價值,而是它是不確定的。我錯過了什麼?

回答

6

簡短的回答:讓你的link功能期望值foo你必須要觀察的屬性:

attr.$observer('myDirectiveFoo', function(value){ 
    console.log(value); 
    console.log($scope.foo); 
}); 

兩個控制檯輸出將得到預期的bar值。爲什麼?屬性值必須被內插,並且這將在鏈接函數被調用後發生。

龍回答:用於傳遞給鏈接功能Attr對象表示的文檔:

使用$觀察觀察包含插屬性值的變化(例如SRC =「{{酒吧}}」)。這不僅非常高效,而且也是輕鬆獲取實際值的唯一方法,因爲在鏈接階段插值尚未進行評估,因此此時將值設置爲未定義。

讓我們看看您的示例的修改版本。它還顯示了=@範圍的區別。

這是我們的HTML:

<body ng-controller="MainCtrl"> 
    <span my-directive my-directive-foo="hello {{name}}" my-directive-bar="name" ></span> 
</body> 

這是控制器:

app.controller('MainCtrl', function($scope, $timeout, $interpolate){ 
    $scope.name = 'roy'; 
    $timeout(function(){ 
    $scope.name = 'michael'; 
    },4000); 
}); 

正如你可以看到,我們有一個name屬性後,將改變從羅伊邁克爾 4秒。

這是指令:

app.directive('myDirective', function() { 
    return { 
     scope: { 
     foo: '@myDirectiveFoo', 
     bar: '=myDirectiveBar' 
     }, 
     link: function ($scope, iElement, iAttrs, controller) { 
      console.log('link foo: '+$scope.foo); 
      console.log('link bar: '+$scope.bar); 
      iAttrs.$observe('myDirectiveFoo',function(value){ 
       console.log('link observed foo: '+$scope.foo, value);  
      }); 
      $scope.$watch('bar', function(newValue, oldValue){ 
       console.log('watch', oldValue, newValue); 
      }); 
      console.log('link done'); 
     }, 
     controller: function($scope){ 
      console.log('controller foo:'+$scope.foo); 
      console.log('controller bar:'+$scope.bar); 
     } 
    }; 
}); 

我們有兩個獨立的作用域屬性。 foo配置爲單向綁定,而bar配置爲雙向綁定。在控制器輸出中,我們將看到,雙向綁定($ scope.bar)立即可用,單向綁定($ scope.foo)不可用。在鏈接函數中,我們得到了相同的結果。如果鏈接完成,我們將看到觀察者和觀察者將用當前(和預期)值進行激發。如果名稱屬性在4秒後更改了值,觀察者和觀察者將再次觸發。

現場觀看@PLUNKR

+0

感謝邁克爾,需要一些時間來消化這一個:) –