[英]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.