无法调用 Angular 指令方法
Unable to call Angular directive method
我有一个Angular观点:
<div ng-include="'components/navbar/navbar.html'" class="ui centered grid" id="navbar" onload="setDropdown()"></div>
<div class="sixteen wide centered column full-height ui grid" style="margin-top:160px">
<!-- other stuff -->
<import-elements></import-elements>
</div>
这是由 UI-Router 控制的,它正在分配控制器,仅供参考。
此视图的控制器如下所示:
angular.module('pcfApp')
.controller('ImportElementsCtrl', function($scope, $http, $location, $stateParams, $timeout, Framework, OfficialFramework) {
$scope.loadOfficialFrameworks();
// other stuff here
});
<import-elements>
指令,如下所示:
angular.module('pcfApp').directive('importElements', function($state, $stateParams, $timeout, $window, Framework, OfficialFramework) {
var link = function(scope, el, attrs) {
scope.loadOfficialFrameworks = function() {
OfficialFramework.query(function(data) {
scope.officialFrameworks = data;
$(".ui.dropdown").dropdown({
onChange: function(value, text, $item) {
loadSections($item.attr("data-id"));
}
});
window.setTimeout(function() {
$(".ui.dropdown").dropdown('set selected', data[0]._id);
}, 0);
});
}
return {
link: link,
replace: true,
templateUrl: "app/importElements/components/import_elements_component.html"
}
});
我的印象是我能够以这种方式从我的控制器调用指令的 loadOfficialFrameworks()
方法(因为我没有指定隔离范围),但我得到了一个方法控制器上的未定义错误。我在这里错过了什么?
指令作用域和控制器作用域是两个不同的对象
你应该在 CTRL 中使用
$scope.$broadcast('loadOfficialFrameworks_event');
//在指令中
scope.$on('loadOfficialFrameworks_event', function(){
scope.loadOfficialFrameworks();
})
问题是您的控制器函数在 link 函数运行之前运行,因此当您尝试调用它时 loadOfficialFrameworks 尚不可用。
试试这个:
angular.module('pcfApp')
.controller('ImportElementsCtrl', function($scope, $http, $location, $stateParams, $timeout, Framework, OfficialFramework) {
//this will fail because loadOfficialFrameworks doesn't exist yet.
//$scope.loadOfficialFrameworks();
//wait until the directive's link function adds loadOfficialFrameworks to $scope
var disconnectWatch = $scope.$watch('loadOfficialFrameworks', function (loadOfficialFrameworks) {
if (loadOfficialFrameworks !== undefined) {
disconnectWatch();
//execute the function now that we know it has finally been added to scope
$scope.loadOfficialFrameworks();
}
});
});
下面是一个 fiddle 的例子:http://jsfiddle.net/81bcofgy/
我有一个Angular观点:
<div ng-include="'components/navbar/navbar.html'" class="ui centered grid" id="navbar" onload="setDropdown()"></div>
<div class="sixteen wide centered column full-height ui grid" style="margin-top:160px">
<!-- other stuff -->
<import-elements></import-elements>
</div>
这是由 UI-Router 控制的,它正在分配控制器,仅供参考。
此视图的控制器如下所示:
angular.module('pcfApp')
.controller('ImportElementsCtrl', function($scope, $http, $location, $stateParams, $timeout, Framework, OfficialFramework) {
$scope.loadOfficialFrameworks();
// other stuff here
});
<import-elements>
指令,如下所示:
angular.module('pcfApp').directive('importElements', function($state, $stateParams, $timeout, $window, Framework, OfficialFramework) {
var link = function(scope, el, attrs) {
scope.loadOfficialFrameworks = function() {
OfficialFramework.query(function(data) {
scope.officialFrameworks = data;
$(".ui.dropdown").dropdown({
onChange: function(value, text, $item) {
loadSections($item.attr("data-id"));
}
});
window.setTimeout(function() {
$(".ui.dropdown").dropdown('set selected', data[0]._id);
}, 0);
});
}
return {
link: link,
replace: true,
templateUrl: "app/importElements/components/import_elements_component.html"
}
});
我的印象是我能够以这种方式从我的控制器调用指令的 loadOfficialFrameworks()
方法(因为我没有指定隔离范围),但我得到了一个方法控制器上的未定义错误。我在这里错过了什么?
指令作用域和控制器作用域是两个不同的对象
你应该在 CTRL 中使用
$scope.$broadcast('loadOfficialFrameworks_event');
//在指令中
scope.$on('loadOfficialFrameworks_event', function(){
scope.loadOfficialFrameworks();
})
问题是您的控制器函数在 link 函数运行之前运行,因此当您尝试调用它时 loadOfficialFrameworks 尚不可用。
试试这个:
angular.module('pcfApp')
.controller('ImportElementsCtrl', function($scope, $http, $location, $stateParams, $timeout, Framework, OfficialFramework) {
//this will fail because loadOfficialFrameworks doesn't exist yet.
//$scope.loadOfficialFrameworks();
//wait until the directive's link function adds loadOfficialFrameworks to $scope
var disconnectWatch = $scope.$watch('loadOfficialFrameworks', function (loadOfficialFrameworks) {
if (loadOfficialFrameworks !== undefined) {
disconnectWatch();
//execute the function now that we know it has finally been added to scope
$scope.loadOfficialFrameworks();
}
});
});
下面是一个 fiddle 的例子:http://jsfiddle.net/81bcofgy/