Как внедрить свой провайдер ng-model?
Описался в заголовке, речь идет не о провайдере, а об адаптере.
Ответили на мой вопрос: http://stackoverflow.com/questions/1...e-in-angularjs По первому пункту посоветовали внедрить в директиву, использующую ng-model собственный адаптер, по аналогии с INPUT, SELECT или TEXTAREA. Что имелось в виду под адаптером? |
Я понять не могу что ты хочешь сделать :)
1) Если тебе ng-model надо внедрить что ли в свою директиву, то вот пример в plunker http://plnkr.co/edit/jSoi1Pa54ECVgdbMSYL7?p=preview Если посмотреть внимательно то из кода видно что родной scope дерективы не используется вообще. ng-model влияет на dom посредством перегруженного метода render Из dom обратно в ngmodel изменения транслируются пр помощи $setViewValue(html); Фаза родного scope никого не колышит. Если проблема не в этом то разъясни в чём, я же не телепат :) 2) с одновременным использованием scope и контролера ngmodel проблем нет, из $render для scope $apply или $digest вызывать ненужно. 3) можно запросто встроить ng-model в scope если написать так scope: { test1: '=ngModel' } Своял рабочую демку. http://plnkr.co/edit/TzclpkqNPbAxzTWEunbQ?p=preview А вот одновременное использование изолированного scope и контролера ng-model привело меня к неожиданным результатам. ngModel.$render срабатывает только при первом запуске а потом забивает на изменение. Как мне кажется это простительно, стандартных watch и apply более чем достаточно для реализации любой задумки. Короче я ни фига не понимаю в чём запарка у тебя. |
Проблема моя в
Из примера видно, что, будучи запущенной в фазе $apply, модель принимает пустое значение. Тут работает только scope[attrs.ngModel].value = 'значение' Вторая проблема в том, что в сложных ситуациях даже этот код не обновляет вид в фазе $digest. Ошибку локализовать не получилось, поэтому принимайте на веру |
Во первых используй более новую версию angular <script src="http://code.angularjs.org/1.2.0rc1/angular.min.js"></script>
Я по прежнему не понимаю в чём прикол. В твоём коде нет смысла. Ситуация абсурдна. Ты используешь контролёр ngModel и можешь реагировать на изменения значения ng-model в рендере. Но блять почему-то тебе этого мало и ты отслеживаешь изменения ещё и при помощи watch. Ну да по фиг. Но млять дальше веселее. Ты вмешиваешься в работу ngModelCtrl из события при чём в фазе $apply (когда ngModelCtrl ещё не полностью инициализирован) тем самым меняя нормальную работу ngModelCtrl и получая неожиданные лулзы в рендере. Получается что ты используешь два взаимоисключающий механизма чтобы при помощи первого(watch) пытаться изменить работу второго(ngModelCtrl) :) Теперь детали. Если говорить о твоём примере то в фазе apply viewValue и modelValue имеет тип число а не object как в фазe digest. Если предположить что viewValue станет объектом при первом срабатывании render(а точнее при первом watch в ngModelCtrl) то твоё событие срабатывает до рендер и в событии ты пытаешся присвоить значение свойству числа. Демонстрация здесь ->http://plnkr.co/edit/WE1oxyNniYgCz5eLUOQu?p=preview // вот что у тебя происходит // как видишь ошибки нет (проверял в хроме), но и свойство не присвоишь. var a=NaN; a.modelView="100500"; alert(a); alert("значение a.modelView= " + a.modelView); ещё одна ошибка в том что ngModel.$viewValue у тебя ОБЬЕКТ, так как model который передаёшь это объект. А ты объект пытаешься отобразить как строку или число. ngModel.$render = function() { //нужно писать element.html(ngModel.$viewValue.value || ''); //не нужно писать //element.html(ngModel.$viewValue || ''); }; Ты хрен пойми чё делаешь, и как следствие у тебя хрен пойми что получается :D |
Вот демка в которой я заставил твой пример отображать фазу, для простоты демки отказался от объекта в model.
Рендер фазу конечно показывать не будет так как при вызове $setViewValue он и не должен срабатывать. Но как известно если хочется то можно и заставить, для этого достаточно вызвать $render в ручную. http://plnkr.co/edit/Ib9FvAVEz6KNYy8myxlj?p=preview если хочется всётаки чтобы render отображал только то что было записано в scope инорируя то что было записано через setViewValue то можно выкрутится и здесь http://plnkr.co/edit/tDX6kT17OZLazRMsU0IH?p=preview Правда я так и не понял на хера этот геморой нужен :D кое какие опыты для кучи 1) директива отображает модели потом меняет её http://plnkr.co/edit/pPxDLxJtF9zTvv6DWy01?p=preview 2) то же самое но при помощи watch http://plnkr.co/edit/sEMvEXGXTwKXOyqKWI0i?p=preview |
Во первых используй более новую версиюА там что-то поменялось в этом плане? Не смотрел еще. Цитата:
|
Цитата:
При установки значения в scope произойдёт срабатывание watch. Рендерить значение в элементе вероятно тоже придётся в watch, то есть рендер сработает независимо от того нужно или нет. При использовании setValue рендер не сработает. То есть производительность выше (правда на чуток). Вероятно ngModelCtrl был выделен из ng-model в целях оптимизации кода. Точнее ответить не могу, разбираться пока с этим моментом не хочется. Я думаю ngModelCtrl имеет ценность только на простых директивах c функционалом вроде input. В более сложных случаях scope должен быть изолированным. |
Часовой пояс GMT +3, время: 22:20. |