簡體   English   中英

鏈接功能和控制器功能如何在角度指令中共享知識?

[英]How can a link function and controller function share knowledge in an angular directive?

我有一個顯示付款歷史的角度指令。 默認情況下,它使用vm.numberOfPaymentsToDisplay變量顯示最近6次付款。 如果單擊“查看更多”,它將增加10。現在,當用戶單擊另一部分時,鏈接功能中會有一個偵聽器,該偵聽器應將數字重置為6,但是vm是未定義的。

這是代碼:

angular.module('nui.settings2.account')
 .directive('paymentHistory', function(){

 function PaymentHistoryController(paymentHistoryService, $filter, $window, $translate){

  const filter = $filter('formatCurrency');

  var vm = this;
  vm.payments = paymentHistoryService.get();
  vm.numberOfPaymentsToDisplay = 6;
  vm.getLastPayment = getLastPayment;
  vm.viewMorePayments = viewMorePayments;
  vm.title = $translate.instant('NUI.SETTINGS.PAYMENT_HISTORY');


  function getLastPayment(){
    const lastTransaction = paymentHistoryService.getLastPayment();
    return lastPaymentInfo = "amount (date)";
  }

  function viewMorePayments(){
    vm.numberOfPaymentsToDisplay = vm.numberOfPaymentsToDisplay + 10;
    return true;
  }
}

function link(scope, element, attrs, [expander, paymentHistory]){
  const containerEl = element.children();
  expander.registerContentContainer(containerEl);
  scope.$on(expander.COLLAPSE_EVENT, () => vm.numberOfPaymentsToDisplay = 6);
  scope.$on("$destroy", () => scope.$emit(expander.CONTAINER_DEREGISTER_EVENT));
  paymentHistory.cancel = () => expander.collapse();
}

return {
  restrict: 'E',
  templateUrl: 'nui/settings2/account/billing/payment-history.directive.html',
  controller: PaymentHistoryController,
  link: link,
  require: ['^^settingExpander', 'paymentHistory'],
  controllerAs: 'PaymentHistoryCtrl',
  bindToController: true
};
});

即使只有控制器知道此知識,如何在鏈接函數中設置vm.numberOfPaymentsToDisplay = 6

您可以在將PaymentHistoryController注入鏈接函數時,將諸如setNumberOfPaymentsToDisplay之類的方法添加到PaymentHistoryController中,您可以像這樣調用該方法:

paymentHistory.setNumberOfPaymentsToDisplay(6);

控制器代碼:

function PaymentHistoryController(paymentHistoryService, $filter, $window, $translate){

  const filter = $filter('formatCurrency');

  var vm = this;
  vm.payments = paymentHistoryService.get();
  vm.numberOfPaymentsToDisplay = 6;
  vm.getLastPayment = getLastPayment;
  vm.viewMorePayments = viewMorePayments;
  vm.setNumberOfPaymentsToDisplay = setNumberOfPaymentsToDisplay;
  vm.title = $translate.instant('NUI.SETTINGS.PAYMENT_HISTORY');


  function getLastPayment(){
    const lastTransaction = paymentHistoryService.getLastPayment();
    return lastPaymentInfo = "amount (date)";
  }

  function viewMorePayments(){
    vm.numberOfPaymentsToDisplay = vm.numberOfPaymentsToDisplay + 10;
    return true;
  }

  function setNumberOfPaymentsToDisplay(amount) {
     vm.numberOfPaymentsToDisplay = amount;
  }
}

鏈接代碼:

function link(scope, element, attrs, [expander, paymentHistory]){
  const containerEl = element.children();
  expander.registerContentContainer(containerEl);
  scope.$on(expander.COLLAPSE_EVENT, () => paymentHistory.setNumberOfPaymentsToDisplay(6));
  scope.$on("$destroy", () => scope.$emit(expander.CONTAINER_DEREGISTER_EVENT));
  paymentHistory.cancel = () => expander.collapse();
}

實際上,您還有更多選擇。 在組件之間共享數據的一般方法是使用服務singleton,即每次在組件內部使用它時都通過angular緩存和注入單個實例。 另一個有效的解決方案是發出事件。

服務內容

.service('MyService', function(){
 var data;
 this.setData = function(newData){
   data = newData;
 }
 this.getData = function(){
  return data;
 }
})

大事記

$rootScope.$broadcast('my.evt', data); //down in the scope chain, visible to any scope
$rootScope.$emit('my.evt', data); //up in the scope chain since is the rootscope only visible to rootScope

$scope.$emit //up in the scope chain
$scope.$broacast //down in the scope chain

聽事件:

$rootScope.$on('my.evt', function(evt, data){ //do something }

要么

$scope.$on('my.evt', function(evt, data){ //do something }

但是,在這種情況下,您將使用鏈接功能來修改業務邏輯,而這不是常規方法,通常該鏈接僅用於處理dom事件和修改dom。 所以我的個人建議是重構您的代碼並將整個業務邏輯放入控制器中

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM