AngularJs не может получить доступ к объекту формы в контроллере ($scope)


Я использую bootstrap-ui более конкретно модальные окна. И у меня есть форма в модальном, что я хочу, чтобы создать экземпляр объекта проверки формы. Так что в основном я делаю это:

<form name="form">
    <div class="form-group">
        <label for="answer_rows">Answer rows:</label>
        <textarea name="answer_rows" ng-model="question.answer_rows"></textarea>
    </div>
</form>

<pre>
    {{form | json}}
</pre

Я могу видеть объект формы в html-файле без проблем, однако, если я хочу получить доступ к объекту проверки формы из контроллера. Он просто выводит мне пустой объект. Вот пример контроллера:

.controller('EditQuestionCtrl', function ($scope, $modalInstance) {
    $scope.question = {};
    $scope.form = {};

    $scope.update = function () {
        console.log($scope.form); //empty object
        console.log($scope.question); // can see form input
    };
});

каковы могут быть причины, по которым я не могу получить доступ $scope.form от контроллер ?

7 65

7 ответов:

только для тех, кто не используя $scope, а this, в их контроллере вам нужно будет добавить псевдоним контроллера, предшествующий имени формы. Например:

<div ng-controller="ClientsController as clients">
  <form name="clients.something">
  </form>
</div>

и затем на контроллере:

app.controller('ClientsController', function() {
  // setting $setPristine()
  this.something.$setPristine();
};

надеюсь, что это также способствует общему набору ответов.

нормальный способ, если ng-контроллер является родителем элемента формы: пожалуйста, удалите эту строку:

$scope.form = {};

если angular устанавливает форму для ваших контроллеров $scope вы перезаписываете его пустым объектом.


как заявил ОП, это не так. Он использует $modal.open, поэтому контроллер не является родителем формы. Я не знаю хорошего решения. Но эту проблему можно взломать:

<form name="form" ng-init="setFormScope(this)">
...

и в контроллер:

$scope.setFormScope= function(scope){
   this.formScope = scope;
}

и позже в вашей функции обновления:

$scope.update = function () {
    console.log(this.formScope.form); 

};

посмотрите на исходный код "модального" углового пользовательского интерфейса bootstrap, вы увидите, что директива имеет

transclude: true

это означает, что модальное окно создаст новую дочернюю область, родителем которой здесь является controller $scope, как родной брат области директивы. Тогда "форма" может быть доступна только для вновь созданной дочерней области.

одним из решений является определение var в области контроллера, например

$scope.forms = {};

затем на имя формы, мы используем что-то вроде forms.formName1. Таким образом, мы все еще можем получить доступ к нему с нашего контроллера, просто позвонив $scope.forms.formName1.

это работает, потому что механизм наследования в JS-это цепочка прототипов. Когда дочерняя область пытается создать forms.formName1, он сначала пытается найти объект forms в своей собственной области, которая определенно не имеет его, так как он создается на лету. Затем он попытается найти его от родителя (до цепочки прототипов), и здесь, поскольку мы определили его в области контроллера, он использует это'forms' объект, который мы создали для определения переменной formName1. В результате мы все еще можем использовать его в контроллер, чтобы делать вещи, как:

if($scope.forms.formName1.$valid){
      //if form is valid
}

подробнее о передача, посмотрите ниже видео-сайт misco от 45 минут. (это, наверное, самое точное объяснение того, что раскрываемый областей, которые я когда-либо находил !!!)

www.youtube.com/watch?v=WqmeI5fZcho

нет необходимости в обмане ng-init, потому что проблема в том, что $scope.form не устанавливается при запуске кода контроллера. Уберите form = {} инициализация и получить доступ к форме с помощью часов:

$scope.$watch('form', function(form) {
  ...
});

Я использую документированный подход.

https://docs.angularjs.org/guide/forms

Итак, пользователь имя формы, на" Сохранить " нажмите, например, просто передать formName в качестве параметра и Эй presto форма доступна в методе сохранения (где formScopeObject greated на основе спецификаций ng-моделей, установленных в форме или если вы редактируете это будет объект хранения элемента редактируется т. е. учетная запись пользователя)

<form name="formExample" novalidate>

<!-- some form stuff here -->
Name
<input type="text" name="aField" ng-model="aField" required="" />

<br /><br />

<input type="button" ng-click="Save(formExample,formScopeObject)" />

</form>

чтобы расширить ответ user1338062: решение, которое я использовал несколько раз, чтобы инициализировать что-то в моем контроллере, но пришлось ждать, пока он не будет фактически доступен для использования:

var myVarWatch = $scope.$watch("myVar", function(){
    if(myVar){
        //do whatever init you need to
        myVarWatch();    //make sure you call this to remove the watch
    }
});

для тех, кто использует Angular 1.5, мое решение было$, наблюдая за формой на этапе $postlink:

$postLink() {
      this.$scope.$watch(() => this.$scope.form.$valid, () => {
      });
    }