angularjs - 如何使 $watch 函数在测试中执行?

标签 angularjs angularjs-directive

我正在实现一个简单的指令,该指令表示一个表单字段,其所有附加内容(如标签、错误字段、正则表达式)都在一行中。

该指令如下:

 <div ng-controller="parentController">

        {{username}}
<!-- the directive -- > 
        <form-field label="Username:" regex="someRegex" constrainsViolationMessage="someValidationMessage" model="username" place-holder="some input value">
        </form-field>
    </div>

现在,我想测试指令范围和父范围之间的数据绑定(bind)。

测试是:
it("should bind input field to the scope variable provided by parent scope ! ", function () {
        var formInput = ele.find('.form-input');
        formInput.val("some input");
        expect(ele.find('p').text()).toEqual('some input');
    });

这个问题是我不知道为什么测试没有通过,即使指令正常工作。 Here is a fiddle of the directive.

这是整个测试和测试设置。
var formsModule = angular.module('forms', []);

formsModule.controller('parentController', function ($scope) {
});


formsModule.directive('formField', function () {

    var label;
    var constrainsViolationMessage;
    var placeHolder;
    var model;


    return {
        restrict:'E',
        transclude:true,
        replace:false,
        scope:{
            model:'='
        },
        link:function (scope, element, attr) {

            console.log("link function is executed .... ");

            scope.$watch('formInput', function (newValue, oldValue) {
                console.log("watch function is executed .... !")
                scope.model = newValue;
            });
            scope.label = attr.label;
        },
        template:'<div class="control-group ">' +

            '<div class="form-label control-label">{{label}}</div> ' +

            '<div class="controls controls-row"> ' +

            '<input type="text" size="15" class="form-input input-medium" ng-model="formInput"  placeholder="{{placeHolder}}">' +

            '<label class="error" ng-show={{hasViolationConstrain}}>{{constrainsViolationMessage}}</label>' +

            '</div>'
    }
});


beforeEach(module('forms'));

var ele;

var linkingFunction;

var elementBody;


var scope;
var text = "";
var placeHolder = "filed place holder";
var label = "someLabel";
var regex = "^[a-z]{5}$";


beforeEach(inject(function ($compile, $rootScope) {

        scope = $rootScope;


        elementBody = angular.element('<div ng-controller="parentController">' +
            '<p>{{username}}</p>' +
            '<form-field label="Username:" regex="someRegex" constrainsViolationMessage="someValidationMessage" model="username" place-holder="some input value"> </form-field>');

        ele = $compile(elementBody)(scope);
        scope.$digest();
    }
));


afterEach(function () {
    scope.$destroy();
});


iit("should bind input field to the scope variable provided by parent scope ! ", function () {
    var formInput = ele.find('.form-input');
    formInput.val("some input");
    expect(ele.find('p').text()).toEqual('some input');
});

如您所见,我想断言表单输入反射(reflect)在父范围提供的“模型”属性中设置的范围变量中。

我在这里错过了什么吗?
谢谢你帮助我……!

最佳答案

你错过了 scope.$apply()在设置输入值后调用,因此更改永远不会被消化。在常规应用程序生命周期中,这会自动发生,但您必须在测试中手动触发

看看https://github.com/angular/angular.js/blob/master/test/ng/directive/formSpec.js大量的例子。

关于angularjs - 如何使 $watch 函数在测试中执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15154313/

相关文章:

javascript - 将 json 对象转换为数组以使用 Javascript 遍历 ng-repeat?

javascript - 同时添加两个元素

angularjs - 从模态中以 Angular 更改模态的模板

javascript - Angular : Modify model of parent scope in a directive with '=xxx' isolate scope?

angularjs - 使用组件作为 $mdDialog 的内联模板

javascript - 防止使用 angular.js 提交多个表单 - 禁用表单按钮

angularjs - 如何为 Spring Boot 生成的 XSRF-Token cookie 设置 max-age

rest - 当集合服务返回字典而不是数组时如何使用 Restangular?

angularjs - 我可以实现指令组合吗

Angularjs:使用子指令设置父指令范围值