这是我的指令 mySchedule.directive.js
'use strict';
angular.module('myApp')
.directive('mySchedule', function () {
return {
restrict: 'E',
scope: {
mine: '='
},
templateUrl: 'App/directives/mySchedule.html?v={version}',
controller: ['$scope', 'utils', '$location',
function ($scope, utils, $location) {
$scope.navigateToMySchedule = function (name) {
utils.showConfirmationDialog(
myResources.resourceText.alert_Navigation,
myResources.resourceText.confirmDialog_LeaveCurrentPage,
'Leave page', 'Stay on page').result.then(function () {
$location.path("/myCar/").search("route", name);
//on ok button press
// end on ok button press
}, function () {
//on cancel button press
});
}
}]
};
});
这是我的测试文件 mySchedule.directive.spec.js
/// <reference path="../../../chutzpah.conf.js" />
'use strict';
describe('mySchedule Directive', function () {
var $httpBackend;
var $scope;
var $compile;
var utilsService;
var $location;
var controller;
var $controller;
beforeEach(module('myApp', function ($provide) {
}));
beforeEach(
inject(function ($rootScope, _$compile_, $injector, _$location_, utils, _$controller_) {
$httpBackend = $injector.get('$httpBackend');
$httpBackend.whenGET('App/directives/mySchedule.html').respond(200, 'OK');
$scope = $rootScope.$new();
$compile = _$compile_;
$location = _$location_;
$controller = _$controller_;
utilsService = utils
utilsService.showconfirmationdialog = function () {
return true;
}
})
);
afterEach(function () {
$httpBackend.verifyNoOutstandingExpectation();
});
it('should redirect to my schedule', function () {
var element = angular.element('<my-schedule></my-schedule');
var testcase = "name"
element = $compile(element)($scope);
//$httpBackend.flush();
$scope.$digest();
// NOW NONE OF THESE LINES AFTER THIS WORK
element.isolateScope().navigateToMySchedule(testcase);
var controller = $controller('mySchedule', { '$scope': $scope });
$scope.navigateToMySchedule(testcase);
controller.navigateToMySchedule(testcase);
expect(location.path).toEqual("/route=name");
});
});
- Controller 未定义
- element.isolateScope() 未定义
- $scope.navigateToMySchedule(testcase) 给出 Object doesn't support property or method 'navigateToMySchedule' 错误
最佳答案
确保没有任何内容覆盖函数module
,并且您包含了ngMock
。一种确定的方法是直接调用 angular.mock.module
,比如
beforeEach(angular.mock.module('myApp', function ($provide) {}));
使用 $httpBackend
进行 mocking templateUrl
不会工作,现在,你的 directive
没有被已创建,因此您的所有代码都失败了。
一种简单易行的方法是使用 $templateCache
beforeEach(function () {
$templateCache.put('App/directives/mySchedule.html', '<div>OK</div>');
});
现在,如果您的模板被mocked成功,调用element.isolateScope()
应该没问题,但后面的行不行。
$controller
检查是否通过 $controllerProvider
注册了具有给定名称的 Controller ,如果评估当前作用域上的字符串返回一个构造函数,则您的 Controller 被声明为内联指令
所以它不会被发现。如果要获取 Controller ,请使用 element.controller('mySchedule')
。
controller.navigateToMySchedule
将失败,因为该函数在 $scope
中而不是在 Controller 中,我的意思是,您将函数声明为 $scope。 navigateToMySchedule = function (name)
而不是 this.navigateToMySchedule = function (name)
。注意到区别了吗?
$scope.navigateToMySchedule
将失败,因为变量 $scope
不包含指令的范围。调用 element.isolateScope()
就足够了,对吧?但您也可以使用 element.children().scope()
获取它。
这是我在本地做的一个小测试来模仿你的。
首先,模块和指令:
(function () {
'use strict';
angular.module('myApp', []);
})();
(function () {
'use strict';
angular.module('myApp')
.directive('mySchedule', function () {
return {
restrict: 'E',
scope: {
mine: '='
},
templateUrl: 'App/directives/mySchedule.html',
controller: function ($scope) {
this.navigateToMySchedule = function (name) {
return name;
}
}
};
});
})();
这里是测试
describe('mySchedule Directive', function () {
var $scope;
var $compile;
var $templateCache;
beforeEach(angular.mock.module('myApp', function ($provide) {}));
beforeEach(
inject(['$rootScope', '$compile', '$templateCache',
function ($rootScope, _$compile, _$templateCache) {
$scope = $rootScope.$new();
$compile = _$compile;
$templateCache = _$templateCache;
}])
);
beforeEach(function () {
$templateCache.put('App/directives/mySchedule.html', '<div>OK</div>');
});
it("$scope should exist", function () {
expect($scope).toBeDefined();
expect($compile).toBeDefined();
});
it('should redirect to my schedule', function () {
var element = angular.element('<my-schedule></my-schedule');
var testcase = "name"
element = $compile(element)($scope);
$scope.$digest();
var controller = element.controller('mySchedule');
expect(controller).toBeDefined();
expect(controller.navigateToMySchedule).toBeDefined();
expect(controller.navigateToMySchedule(testcase)).toEqual(testcase);
});
});
请注意,我只是注入(inject)了运行此测试所需的内容,您可能需要更多。此外,我在 directive
中使用 this
来声明函数 navigateToMySchedule
,这样我就可以从 Controller 实例中调用它。
嗯,希望对你有帮助
关于javascript - 如何访问指令内部的 Controller 内部功能?一切都返回未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51663896/