Javascript-форум (https://javascript.ru/forum/)
-   Angular.js (https://javascript.ru/forum/angular/)
-   -   Как внедрить свой провайдер ng-model? (https://javascript.ru/forum/angular/40757-kak-vnedrit-svojj-provajjder-ng-model.html)

Shitbox2 19.08.2013 01:54

Как внедрить свой провайдер ng-model?
 
Описался в заголовке, речь идет не о провайдере, а об адаптере.

Ответили на мой вопрос:
http://stackoverflow.com/questions/1...e-in-angularjs

По первому пункту посоветовали внедрить в директиву, использующую ng-model собственный адаптер, по аналогии с INPUT, SELECT или TEXTAREA. Что имелось в виду под адаптером?

DjDiablo 22.08.2013 12:46

Я понять не могу что ты хочешь сделать :)

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 более чем достаточно для реализации любой задумки.

Короче я ни фига не понимаю в чём запарка у тебя.

Shitbox2 23.08.2013 00:36

Проблема моя в буржуях докторообразных, в обновлении модели (и, соответственно, вида) из директивы. $render не работает: http://plnkr.co/edit/6AXgnyHV6PJEcBDxrbJJ?p=preview

Из примера видно, что, будучи запущенной в фазе $apply, модель принимает пустое значение. Тут работает только scope[attrs.ngModel].value = 'значение'

Вторая проблема в том, что в сложных ситуациях даже этот код не обновляет вид в фазе $digest. Ошибку локализовать не получилось, поэтому принимайте на веру

DjDiablo 23.08.2013 03:50

Во первых используй более новую версию 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

DjDiablo 23.08.2013 10:10

Вот демка в которой я заставил твой пример отображать фазу, для простоты демки отказался от объекта в 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

Shitbox2 23.08.2013 21:58

Во первых используй более новую версию
А там что-то поменялось в этом плане? Не смотрел еще.

Цитата:

Правда я так и не понял на хера этот геморой нужен
Если звезды зажигают, значит это кому-нибудь нужно :-) В исходниках Ангуляра никто не работает с ng-model внутри директив как с scope[attrs.ngModel].value = 'значение'. Тут я скорее пытаюсь выяснить область применения ng-model. Зачем, вообще, нужны все эти методы setViewValue, если можно по-простому?

DjDiablo 26.08.2013 18:32

Цитата:

Если звезды зажигают, значит это кому-нибудь нужно :-)
Вроде как дети ищут всегда виновника, отсюда и корни креационизма. А мне в детстве было как то по фиг, никогда не думал нужно это кому или нет :) Либо я неправильный, либо психологи слишком умничают :)

При установки значения в scope произойдёт срабатывание watch. Рендерить значение в элементе вероятно тоже придётся в watch, то есть рендер сработает независимо от того нужно или нет.

При использовании setValue рендер не сработает. То есть производительность выше (правда на чуток).

Вероятно ngModelCtrl был выделен из ng-model в целях оптимизации кода.

Точнее ответить не могу, разбираться пока с этим моментом не хочется. Я думаю ngModelCtrl имеет ценность только на простых директивах c функционалом вроде input. В более сложных случаях scope должен быть изолированным.


Часовой пояс GMT +3, время: 22:20.