12

ラベル、エラーフィールド、正規表現などのすべての追加機能をすべて1行で含むフォームフィールドを表す単純なディレクティブを実装しています。

ディレクティブは次のとおりです。

 <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>

次に、ディレクティブスコープと親スコープの間のデータバインディングをテストします。

テストは次のとおりです。

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');
    });

この問題は、ディレクティブが正しく機能していても、なぜテストに合格しないのかわからないことです。これがディレクティブのフィドルです。

そして、これがテスト全体とテストのセットアップです。

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');
});

ご覧のとおり、フォーム入力は、親スコープによって提供される「model」属性に設定されたスコープ変数に反映されていることを表明したいと思います。

私はここで何かが欠けていますか?私を助けてくれてありがとう ... !

4

2 に答える 2

28

scope.$apply()入力値を設定した後、呼び出しが欠落しているため、変更が消化されることはありません。通常のアプリケーションライフサイクルでは、これは自動的に発生しますが、テストで手動でトリガーする必要があります

たくさんの例については、 https://github.com/angular/angular.js/blob/master/test/ng/directive/formSpec.jsをご覧ください。

于 2013-04-05T15:10:01.830 に答える
7

監視を実行する条件を追加した後、$scope。$digest()を使用します。時計を発射します。

于 2013-06-25T11:00:24.213 に答える