[英]How to pass controller data to a custom directive in AngularJS?
我在AngularJS中有一個自定義指令,我想從控制器中將變量傳遞給它。
angular.
module('orderOverview').
component('orderOverview', {
templateUrl: 'home-page/order-overview/order-overview.template.html',
controller: ['Orders',
function ControllerFunction(Orders) {
var self = this;
// Order Info
Orders.getOverview().$promise.then(function(data) {
self.LineItems = data;
});
// Order Info
}
]
});
angular.
module('myApp').
directive('gvInitializeOrderStatus', function() {
return {
scope: {
field: '@',
myData: '='
},
link: function(scope, element) {
console.log('field:', scope.field);
console.log('data:', scope.myData);
}
}
});
<div gv-initialize-order-status field="InquiryDone" myData="$ctrl.LineItems">
<span class="tooltiptext">Inquiry</span>
</div>
當我加載頁面時, field
記錄很好,但是data
未定義。
我已經嘗試了很多方法,但是如果它可以讓您對我的想法有所了解,這就是我應該想到的方法。
在同一模板的另一點上,我將ng-repeat
數據傳遞給指令就好了,但是在這種情況下,我特別不想ng-repeat
<li ng-repeat="lineItem in $ctrl.LineItems">
<div class="status-circle"
ng-click="toggleCircle($event, lineItem, 'InquiryDone')"
field="InquiryDone" item="lineItem" gv-initialize-statuses>
<span class="tooltiptext">Inquiry</span>
</div>
</li>
在我的另一個指令gv-initialize-statuses
,我在我的scope
對象中使用了相同的概念,並且具有類似scope: { 'field': '=' }
,並且效果很好。
如何不使用ng-repeat來完成此操作?
=
雙向綁定 該指令需要在鏈接函數中使用$ watch:
app.directive('gvInitializeOrderStatus', function() {
return {
scope: {
field: '@',
̶m̶y̶D̶a̶t̶a̶:̶ ̶'̶=̶'̶
myData: '<'
},
link: function(scope, element) {
console.log('field:', scope.field);
console.log('data:', scope.myData);
scope.$watch('myData', function(value) {
console.log('data:', scope.myData);
});
}
}
});
諸如ng-repeat
指令會自動使用觀察程序。
同樣出於性能原因,應避免與=
雙向綁定。 與<
的單向綁定更有效。
要獲得更有效的代碼,請在控制器中使用$onChanges
生命周期掛鈎 :
app.directive('gvInitializeOrderStatus', function() {
return {
scope: {
field: '@',
̶m̶y̶D̶a̶t̶a̶:̶ ̶'̶=̶'̶
myData: '<'
},
bindToController: true,
controllerAs: "$ctrl",
controller: function() {
console.log('field:', this.field);
console.log('data:', this.myData);
this.$onChanges = function(changes) {
if (changes.myData)
console.log('data:', changes.myData.currentValue);
};
});
}
}
});
這樣做將使代碼更高效,並且更容易遷移到Angular 2+。
有不同級別的監視:
ng-repeat
指令實際上使用$ watchCollection 。
該指令可能需要使用$doCheck
Life-Cycle hook 。
有關更多信息,請參見
如果只需要指令中的數據,請執行此操作
Orders.getOverview().$promise.then(function(data) {
self.LineItems = data;
$rootScope.$broadcast('myData', data);
});
並且在您的指令中只需使用回調函數捕獲此事件
$scope.$on('myData', function(event, args) {
var anyThing = args;
// do what you want to do
});
問題是$promise
。
指令激活時self.LineItems
尚未准備就緒。 這就是為什么數據undefined
的原因。
也許ng-if
可以幫助您:
<div ng-if="$ctrl.LineItems" gv-initialize-order-status field="InquiryDone" myData="$ctrl.LineItems">
<span class="tooltiptext">Inquiry</span>
</div>
希望這可以幫助。 祝好運!
因此,當我在文檔中閱讀有關$ compile時,我找到了一個有效的答案。 我意識到可以獲取插值的屬性值,因此我從范圍對象中刪除了myData
字段,而是像這樣通過attrs
對象訪問了該值。
angular.
module('myApp').
directive('gvInitializeOrderStatus', function() {
return {
scope: {
field: '@'
},
link: function(scope, element, attrs) {
console.log('field:', scope.field);
console.log('attrs:', attrs);
attrs.$observe('lineItems', function(value) {
console.log(value);
})
}
}
});
<div gv-initialize-order-status field="InquiryDone" lineItems="{{$ctrl.LineItems}}">
<span class="tooltiptext">Inquiry</span>
</div>
請注意,在lineItems屬性中添加了{{ }}
。 attrs.$observe
塊也使我可以知道該值的更改。
在指令中
angular.
module('myApp').
directive('gvInitializeOrderStatus', function() {
return {
scope: {
field: '@',
ngModel: '=' // <- access data with this (ngModel to ng-model in view)
},
link: function(scope, element) {
console.log('field:', scope.field);
console.log('data:', scope.ngModel);
}
}
});
鑒於
<div gv-initialize-order-status field="InquiryDone" ng-model="$ctrl.LineItems">
<span class="tooltiptext">Inquiry</span>
</div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.