簡體   English   中英

需要父FormController的指令中的角度(作用域?)問題

[英]Angular (scope?) issues in a Directive that requires the parent FormController

這是一個人為的示例,但是它說明了我遇到的一個問題。

我有一個具有使用指令生成的輸入的表單。 該代碼類似於以下內容。 小提琴在這里http://jsfiddle.net/technicolorenvy/CFynn/2/

視圖

    <div ng-controller="AppController">
        <form name="myForm">
            <input name="myInput" id="myInput" ng-model="myInputModel" ng-pattern="/\d+/" my-directive required/>
            <button type="submit" ng-click="submitForm()">Submit</button>
        </form>
    </div>

控制者

    app.controller('AppController', function ($scope) {
        $scope.submitForm = function () {
            console.log('form controller inside AppController submitForm()');
            console.log(angular.copy($scope.myForm));
            console.log('is the form valid? ' + $scope.myForm.$valid);
            console.log(' ');
        };
    });

指示

    app.directive('myDirective', function () {
        return {
            template: '<div><input/></div>',
            replace: true,
            restrict: 'A',
            require: '^form',
            compile: function (element, attrs) {
                // some setup here
                // move the id and ng-model down onto the enclosed input
                element.removeAttr('id').removeAttr('ng-model').removeAttr('name');
                element.find('input').attr('id', attrs.id).attr('ng-model', attrs.ngModel).attr('name', attrs.name);

                var inputName = attrs.name,
                    $input = element.find('input');
                if (attrs.required) {
                    element.removeAttr('required');
                    $input.attr('required', true);
                }
                if (attrs.ngPattern) {
                    element.removeAttr('ng-pattern');
                    $input.attr('ng-pattern', attrs.ngPattern);
                }

                return {
                    pre: function (scope, element, attrs, formCtrl) {
                        var patternErrs,
                        fakeNum = 1234;

                        $input.on('change', function () {
                            patternErrs = formCtrl.$error.pattern;
                            if (patternErrs && patternErrs.length > 0) {
                                angular.forEach(patternErrs, function (err) {
                                    if (err.$name === inputName) {
                                        $input.val(fakeNum);
                                        formCtrl[inputName].$setViewValue(fakeNum);
                                        formCtrl[inputName].$setValidity('pattern', true);
                                    }
                                });
                            }
                            console.log('formCtrl inside directive');
                            console.log(angular.copy(formCtrl));
                            console.log('is the form valid? ' + formCtrl.$valid);
                            console.log(' ');
                        });
                    }
                };
            }
        }
    });

在指令中,我在“生成的”輸入上有一個onChange事件,用於檢查與該輸入的名稱匹配的模式錯誤,然后如果有的話,使用setViewValue使用偽值強制數據為我們所需要的,然后設置有效性使用setValidity

這行得通... 問題是,在FIRST提交時,該表格始終無效。 您必須單擊“提交兩次”,該表格才被視為有效。 (以下包括步驟)

  1. 在輸入中輸入字符串(例如'abcd')
  2. 輸入的模式驗證失敗,然后獲得一個有效值(1234)
  3. 指令“ myDirective”處理此+設置輸入的值和有效性
  4. 但是,在FIRST sumbit上,該表格無效
  5. 在SECOND提交時,輸入保持不變,該表格有效

因此,如何在第一次提交表單時使表單有效,而又不加強表單的有效性(閱讀,我不希望手動將表單設置為有效)。 這似乎是一個范圍界定的問題,但是如果是這樣,我不太確定如何解決。

謝謝!

完成更改范圍后,需要在更改事件中調用scope.$apply()

就是說.. 我不確定您要在這里做什么。

看來您可能正在嘗試以復雜的方式解決一個簡單的問題。 顯然,該代碼不是可測試的。 也許正在執行的某些操作實際上是可以封裝在控制器中的“業務邏輯”?

這里的確切目標是什么?

$ input.on('change')中的代碼永遠不會被消化...也就是說,在您的change事件之后,Angular永遠不知道要運行其所有監視和內部過程。 因此,它將在第一次摘要(第一次運行Submit)時運行它。

我認為,如果您將該位包裝在$ timeout()或使用$ scope。$ apply()中,它將解決此問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM