我在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的情况下完成此操作?
答案 0 :(得分:1)
=
进行双向绑定该指令需要在链接函数中使用$ 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
life-cycle hook:
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。
有关更多信息,请参见
答案 1 :(得分:0)
如果您只想要指令中的数据,请执行此操作
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
});
答案 2 :(得分:0)
问题出在$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>
希望这会有所帮助。祝你好运!
答案 3 :(得分:0)
因此,当我在文档中阅读有关$ 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
块也使我可以知道该值的更改。
答案 4 :(得分:-1)
在指令中
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>