2016-04-22 3 views
2

У меня есть следующие (https://jsfiddle.net/f30bj43t/5/) HTML:Угловая настраиваемая директива валидации. Получить ошибки из модели представления

<div ng-controller="DataController as vm"> 
    <div ng-repeat="name in vm.users track by $index">{{name}}</div> 
    <form name="form" validation="vm.errors"> 
    <input validator ng-model="vm.name" name="vm.name" placeholder="name" type="text" /> 
    <a href="#" ng-click="vm.add(vm.name)">Add</a> 
    </form> 
</div> 

Эта форма добавляет имена в список и контроллер является:

app.controller("DataController", DataController); 

function DataController() { 
    var vm = this; 
    vm.name = "Mary"; 
    vm.users = ["Alice", "Peter"]; 
    vm.errors = []; 
    vm.add = function(name) { 
    if (name == "Mary") { 
     var error = { property: "name", message: "name cannot be Mary"}; 
     if (vm.errors.length == 0) 
     vm.errors.push(error);   
     } else { 
     vm.users.push(name);  
     vm.errors = []; 
     }  
    } 
} 

На форме я добавил validation="vm.errors" который определяет, какая переменная содержит ошибки, которые должны использоваться в каждом валидатор ...

Th еп в каждом валидатора директивы Я буду использовать эту переменную, чтобы выбрать правильную ошибку и отобразить его ...

app.directive("validation", validation); 

function validation() { 

    var validation = { 
    controller: ["$scope", controller], 
    replace: false, 
    restrict: "A", 
    scope: { 
     validation: "=" 
    } 
    }; 

    return validation; 

    function controller($scope) { 
    this.getErrors = function() { 
     return $scope.validation; 
    }  
    } 

} 

app.directive("validator", validator); 

function validator() { 

    var validator = { 
    link: link, 
    replace: false, 
    require: "^validation", 
    restrict: "A" 
    }; 

    return validator; 

    function link(scope, element, attributes, controller) {  
    var errors = controller.getErrors(); 
    console.log(errors);  
    // do something with errors 
    } 

} 

ПРОБЛЕМА

В функции связи директивы валидатор мне нужно отслеживать изменения переменной, прошедшей проверку = "vm.errors", поэтому я могу в каждом валидаторе проверить, произошла ли ошибка и принять меры.

Но console.log (ошибки), кажется, не имеют никакого эффекта ...

Как я могу решить эту проблему?

+0

испытаны ли вы свой JSFiddle? Он работает неправильно –

+0

Просто обновил его: https://jsfiddle.net/f30bj43t/5/. Кстати, проблема с предыдущим скрипачом заключалась в том, что перемещение валидатора из формы в внешний div, где у меня есть контроллер, дает мне эту ошибку ... Это то, что я тоже хотел решить. –

ответ

1

Вы можете сделать это либо $watch, либо $broadcast и $on.
Я предпочитаю использовать $on, потому что просмотр переменной потребляет больше, чем прослушивание события, и я бы сказал, что для вашего случая лучше использовать $ broadcast и $ on, потому что вы не смотрите переменную области видимости, но переменная от контроллера.

Если вы хотите узнать больше о $, и $ часы, вот предложение: Angular JS $watch vs $on

А вот ваш JSFiddle с изменениями.

+0

Gabriel, к сожалению, я не могу использовать ваш пример, поскольку мне нужно, чтобы вся работа выполнялась со стороны директив ... Поэтому это должна быть директива, чтобы наблюдать, что происходит в переменной, определенной в validation = "vm.errors". Поэтому я думаю, что способ сделать это - использовать часы. Моя идея была примерно такой: https://jsfiddle.net/q0dy20nv/1/ ... Можете ли вы помочь мне в создании этой работы ... Это была моя самая большая проблема. –

+0

Прошу прощения за то, что я так долго отвечал, я был занят. Теперь я только что обновил JSFiddle, пожалуйста, проверьте и сообщите, удовлетворяет ли он вашим потребностям. =) –

+0

Я следовал за вашим примером, но случилось что-то странное. Если переменная не является массивом, и я смотрю ее, а не смотрю ее длину, часы срабатывают только один раз ... У вас есть идея, почему? Я разветвил ваш пример именно с этим изменением: https://jsfiddle.net/qb8o006h/2/ –

1

Здесь у вас есть рабочий jsfiddle: https://jsfiddle.net/f30bj43t/8/

Я протоколирование переменной vm.errors в консоль каждый раз, когда она меняется:

function link(scope, element, attributes, controller) { 
    scope.$watch('vm.errors.length', function() { 
     if(scope.vm.errors){ 
      console.log(scope.vm.errors); 
     } 
    }); 
} 

Это возможно из-за масштабами наследования. В вашем случае vm - это переменная, добавленная в область действия контроллера, и все директивы внутри этой области наследуют ее по умолчанию (есть способы избежать этого).

В любом случае, похоже, вы создаете слишком много указаний. На ваш случай, для меня было бы достаточно иметь все в контроллере.

Приветствия

Хавьер

+0

Извините, но это не сработает для меня ... Я уже это сделал. Проблема заключается в одной странице, у меня могут быть несколько контроллеров с vm1, vm2 и т. Д. Вот почему я использую validation = "vm.errors". Чтобы указать, где ошибки. Это моя главная проблема ... Мне нужно указать в validation = "vm1.errors", какова переменная для просмотра. Посмотрите, почему ваш пример не будет работать: https://jsfiddle.net/cLqa1gqd/1/. –

Смежные вопросы