使用ngMessage属性编译新元素时出现Angularjs错误

时间:2015-04-06 21:52:01

标签: javascript asp.net-mvc angularjs twitter-bootstrap angularjs-directive

我有以下指令,用于将bootstrap验证项添加到表单中的所有form-group div:

app.directive('bsValidate',($compile: ng.ICompileService) => {
    return {
        restrict: "A",
        link: (scope, element, attrs, ctrl) => {

            function showValidation(formGroupEl: ng.IAugmentedJQuery) {

                var input = formGroupEl.find('input[ng-model],select[ng-model],textarea[ng-model]');
                if (input.length === 0)
                    return;

                var formNameExt = formGroupEl.closest('form').attr('name') + "." + input.attr('name');
                var feedback = $compile('<div ng-messages="' + formNameExt + '" ng-show="' + formNameExt + '.$dirty">')(scope);

                feedback.append($compile('<span ng-message="$valid" class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>')(scope));
                feedback.append($compile('<span ng-message="$invalid" class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>')(scope));

                formGroupEl.addClass('has-feedback');
                formGroupEl.append(feedback);

                scope.$watch(
                    () => {
                        var val = scope[formGroupEl.closest('form').attr('name')][input.attr('name')];
                        return val.$invalid && (val.$touched || val.$dirty);
                    },(isValid) => {
                        formGroupEl.toggleClass('has-error', isValid);
                    });

                scope.$watch(
                    () => {
                        var val = scope[formGroupEl.closest('form').attr('name')][input.attr('name')];
                        return val.$valid && (val.$touched || val.$dirty);
                    },(isValid) => {
                        formGroupEl.toggleClass('has-success', isValid);
                    });
            }

            if (element.get(0).nodeName.toLowerCase() === 'form') {
                element.find('.form-group').each((i, formGroup) => {
                    showValidation(angular.element(formGroup));
                });
            } else {
                showValidation(element);
            }


        }

    };
});

这是我正在使用该指令的Html:

        @using (Html.BeginForm("Contact", "Home", FormMethod.Post, new { @class = "form-horizontal", role = "form", name = "comment_form" }))
        {

                <div class="form-group" bs-validate>
                    @Html.TextBoxFor(m => m.Name, new { @class = "form-control input-lg focus-start", placeholder = "Your Name", ng_model = "name", required = true })
                    <div ng-messages="comment_form.Name.$error" ng-show="comment_form.Name.$dirty">
                        <span class="help-block" ng-message="required">
                            Your Name is required.
                        </span>
                    </div>
                </div>
        }

运行应用程序时出现以下错误消息:

Error: [$compile:ctreq] Controller 'ngMessages', required by directive 'ngMessage', can't be found! 

当我尝试将消息传递元素添加到表单组元素时,会出现错误。如果我评论这些线,一切都按预期工作!此外,我的模板也正常工作:

                <div class="form-group has-feedback" ng-class="{'has-error': comment_form.Name.$invalid && (comment_form.Name.$touched || comment_form.Name.$dirty), 'has-success': comment_form.Name.$valid && comment_form.Name.$dirty}">
                    @Html.TextBoxFor(m => m.Name, new { @class = "form-control input-lg focus-start", placeholder = "Your Name", ng_model = "name", required = true })
                    <div ng-messages="comment_form.Name" ng-show="comment_form.Name.$dirty">
                        <span ng-message="$valid" class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>
                        <span ng-message="$invalid" class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>
                    </div>
                    <div ng-messages="comment_form.Name.$error" ng-show="comment_form.Name.$dirty">
                        <span class="help-block" ng-message="required">
                            Your Name is required.
                        </span>
                    </div>
                </div>

我需要做些什么才能让$compile服务在我的指令中工作?

修改

我刚刚找到了一个有效的解决方案,但感觉有些束缚。

如果我用以下内容替换feedback元素,则可以:

var feedback = $('<div ng-messages="' + formNameExt + '" ng-show="' + formNameExt + '.$dirty">');
var validFeedback = $('<span ng-message="$valid" class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>');
var invalidFeedback = $('<span ng-message="$invalid" class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>');

formGroupEl.append(feedback);
$compile(feedback)(scope);

feedback.append(validFeedback);
feedback.append(invalidFeedback);

$compile(validFeedback)(scope);
$compile(invalidFeedback)(scope);

有更好的方法吗?

0 个答案:

没有答案