2017-05-26 38 views
1

我有一個指令設置是這樣的:angularjs bindToController不能調用方法

angular.module('widget.directives').directive('applePay', applePay); 

function applePay() { 
    return { 
     restrict: 'A', 
     controller: 'ApplePayController', 
     controllerAs: 'controller', 
     scope: { 
      onCheckComplete: '&applePay' 
     }, 
     bindToController: true, 
     templateUrl: 'app/directives/apple-pay/apple-pay.html', 
     link: function (scope, element, attrs, controller) { 
      element.find('button').bind('click', controller.checkout); 
     } 
    }; 
}; 

而且它的控制器是這樣的:

angular.module('widget.directives').controller('ApplePayController', applePayController); 

applePayController.$inject = ['applePayService']; 

function applePayController(applePayService) { 
    var self = this; 

    // Method binding 
    self.checkout = checkout; 

    init(); 

    ////////////////////////////////////////////////// 

    function init() { 
     applePayService.checkAvailability(setAvailability); 
    }; 

    function setAvailability(available) { 
     self.available = available === true; 
     console.log(self); 
     self.onCheckComplete({ available: self.available }); 
    }; 

    function checkout(e) { 
     applePayService.checkout(e, onComplete, onError); 
    }; 

    function onComplete(result, completion) { 
     console.log(result, completion); 
    }; 

    function onError(error) { 
     self.error = error; 
    }; 
}; 

我的這個網站是這樣的:

<div apple-pay="controller.applePayAvailable(available)"></div> 

當指令加載時出現錯誤:

TypeError: self.onCheckComplete is not a function

有誰知道爲什麼? 我有一個類似的指令,工作正常。

+0

在函數'setAvailability'中調用了這個函數'self.onCheckComplete({available:self.available});'但它看起來並沒有在控制器裏面定義 – quirimmo

+0

不,實際上我已經知道了。這是因爲在將範圍綁定到控制器之前,在控制器中調用init。我不得不將init方法添加到鏈接方法 – r3plica

+0

這不是1.6中推薦的方法。 – TSmith

回答

0

這是因爲控制器有控制器實例化時調用的init方法。問題在於範圍還沒有受到約束。所以我必須將控制器更改爲:

angular.module('widget.directives').controller('ApplePayController', applePayController); 

applePayController.$inject = ['applePayService']; 

function applePayController(applePayService) { 
    var self = this; 

    // Method binding 
    self.init = init; 
    self.checkout = checkout; 

    ////////////////////////////////////////////////// 

    function init() { 
     applePayService.checkAvailability(setAvailability); 
    }; 

    function setAvailability(available) { 
     self.available = available === true; 
     console.log(self); 
     self.onCheckComplete({ available: self.available }); 
    }; 

    function checkout(e) { 
     applePayService.checkout(e, onComplete, onError); 
    }; 

    function onComplete(result, completion) { 
     console.log(result, completion); 
    }; 

    function onError(error) { 
     self.error = error; 
    }; 
}; 

然後將init方法添加到指令的鏈接函數中。

angular.module('widget.directives').directive('applePay', applePay); 

function applePay() { 
    return { 
     restrict: 'A', 
     templateUrl: 'app/directives/apple-pay/apple-pay.html', 
     controller: 'ApplePayController', 
     controllerAs: 'controller', 
     bindToController: true, 
     scope: { 
      onCheckComplete: '&applePay' 
     }, 
     link: function (scope, element, attrs, controller) { 
      element.find('button').bind('click', controller.checkout); 
      controller.init(); 
     } 
    }; 
}; 

從上方加入init方法作爲控制器上的公共方法,然後調用從指令controller.init()之間的唯一區別。這確保了範圍在啓動之前受到約束。

+0

這看起來很奇怪。你使用的是什麼版本的angularJS? – TSmith

+0

1.6.4但我不認爲這很奇怪,它是消化循環的工作方式。控制器在指令之前被實例化,因此範圍在該點不可用。 – r3plica

0

我發現這很奇怪,因爲我有一些1.5x代碼在做同樣的事情沒有問題。在學習1.6x後,我做了一些深入的瞭解,瞭解發生了什麼。影響這裏事物的變化是一個名爲preAssignBindingsEnabled的房產。這個突破變化記錄在gitHub post。這也是遷移document here

在遷移文檔的一部分,還有很大的代碼片段,我想你會發現你的情況有所幫助,讓您保持您的link()功能都是關於DOM操作,而不是擔心調用到控制器。在遷移文檔的Core:Services - > $ compile部分下,它使用1.5x $onInit()鉤子語法顯示一條帶有控制器聲明的指令,以確保綁定在控制器初始化之前存在。

我適應這您的情況:

function applePayController(applePayService) { 
    var self = this; 

    // Method binding 
    self.checkout = checkout; 

    //**Hook below to ensure bindings are set when preAssignBindingsEnabled is 
    //false (default setting with 1.6x**) 

    self.$onInit = init; 

    //init(); 

    function init() { 
    applePayService.checkAvailability(setAvailability); 
    }; 

    . 
    . 
    . 
}; 

一旦綁定所有的設置,控制器的$的OnInit它將自動被稱爲角,並且功能正常執行。希望這提供了一些額外的選擇!

相關問題