如何将控制器数据传递给 AngularJS 中的自定义指令?
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);
}
}
});
HTML
<div gv-initialize-order-status field="InquiryDone" myData="$ctrl.LineItems">
<span class="tooltiptext">Inquiry</span>
</div>
当我加载页面时,field
记录正常,但是 data
未定义。
我已经尝试了很多方法,但如果它能让您了解我在想什么,这就是我的想法。
在同一模板的另一点,我将 ng-repeat
数据传递给一个指令就好了,但在这种情况下,我特别不想 ng-repeat
ng-repeat HTML 成功传递数据
<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 的情况下完成此操作?
如果您只想要指令中的数据,请执行此操作
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
});
在指令中
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>
应避免与 =
的双向绑定
指令需要在link函数中使用$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。
有关详细信息,请参阅
问题是$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);
})
}
}
});
HTML
<div gv-initialize-order-status field="InquiryDone" lineItems="{{$ctrl.LineItems}}">
<span class="tooltiptext">Inquiry</span>
</div>
请注意向 lineItems 属性添加的 {{ }}
。 attrs.$observe
块还让我收到值更改的通知。
我在 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);
}
}
});
HTML
<div gv-initialize-order-status field="InquiryDone" myData="$ctrl.LineItems">
<span class="tooltiptext">Inquiry</span>
</div>
当我加载页面时,field
记录正常,但是 data
未定义。
我已经尝试了很多方法,但如果它能让您了解我在想什么,这就是我的想法。
在同一模板的另一点,我将 ng-repeat
数据传递给一个指令就好了,但在这种情况下,我特别不想 ng-repeat
ng-repeat HTML 成功传递数据
<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 的情况下完成此操作?
如果您只想要指令中的数据,请执行此操作
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
});
在指令中
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>
应避免与 =
的双向绑定
指令需要在link函数中使用$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。
有关详细信息,请参阅
问题是$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);
})
}
}
});
HTML
<div gv-initialize-order-status field="InquiryDone" lineItems="{{$ctrl.LineItems}}">
<span class="tooltiptext">Inquiry</span>
</div>
请注意向 lineItems 属性添加的 {{ }}
。 attrs.$observe
块还让我收到值更改的通知。