Javascript-форум (https://javascript.ru/forum/)
-   Angular.js (https://javascript.ru/forum/angular/)
-   -   Изменение модели в директиве (https://javascript.ru/forum/angular/40384-izmenenie-modeli-v-direktive.html)

Shitbox2 03.08.2013 00:03

Изменение модели в директиве
 
В директиве используется ng-model. Нужно чтобы при определенном событии на элементе (пусть при щелчке для примера) менялся параметр первого элемента модели. Есть два варианта, как это сделать:
require: '?ngModel',
link: function (scope, element, attrs, ngModel) {
    element.bind('someevent', function (e) {
          
        //1 вариант     
        if (typeof ngModel.$modelValue === 'object') {
            ngModel.$modelValue[0].active = true
            ngModel.$setViewValue(ngModel.$modelValue)
            scope.$apply()
        }
       
        //2 вариант              
        if (typeof scope[attrs.ngModel] === 'object') {
            scope[attrs.ngModel][0].active = true
            scope.$apply()
        }     
    })
})

Оба варианта работают, тем не менее, какой предпочтительней?

Но работают они не всегда. При первой загрузке они уже и так находятся в цикле $digest (соответственно, $apply не нужен) и тут проблема: срабатывают они через раз. Т.е. вид может обновиться, а может и нет, как повезет. Какие есть мысли по этому поводу?

nerv_ 03.08.2013 00:11

Цитата:

Сообщение от Shitbox2
Есть два варианта, как это сделать

3. коллбэк в модель контроллер

Цитата:

Сообщение от Shitbox2
Какие есть мысли по этому поводу?

без тестового кода мыслей нет

<!DOCTYPE html>
<html id="ng-app" ng-app="app"> <!-- id="ng-app" IE<8 -->
<head>
    <title>sandbox</title>

    <script src="http://code.angularjs.org/1.1.5/angular.min.js"></script>

    <script>
        angular
                .module( 'directives', [])

                .directive( 'ngMy', function() {
                    return {
                        scope: {
                            callback: '&'
                        },
                        link: function( $scope, $element ) {
                            $element.bind( 'click', function() {
                                console.log( 1 );
                                $scope.callback();
                            });
                        }
                    };
                });


        var app = angular.module( 'app', [ 'directives' ]);


        app.controller( 'MainController', function( $scope, $http ) {
            $scope.fn = function() {
                console.log( 2 );
            };
        });

    </script>

</head>
<body ng-controller="MainController">

    <div ng-my callback="fn()" style="background-color: lavender;  height: 100px;">
        click on this element and see in console
    </div>

</body>
</html>

Shitbox2 03.08.2013 15:17

Там большой джикверевский плагин, не могу пример показать... Эмулировать $digest никак не получилось, зато получилось с $apply.

Пример: http://plnkr.co/edit/MxCFH5WzUBAdbEuMRBH2?p=preview

Смысл в том, что при загрузке обновляется модель и $apply запущен, но в вид не обновляется.

Shitbox2 03.08.2013 22:38

Продвинулся дальше в понимании причин http://stackoverflow.com/questions/1...e-in-angularjs
Сорри, что на английском, уже нет сил переводить.

nerv_ 03.08.2013 23:32

Начну с того, что я не понимаю, зачем ты пытаешься обновить модель в директиве. Директивы для работы с DOM. С моделью работают контроллеры.

Зачем директива ng-model помещена внутрь элемента div?
<div my-directive ng-model="model"></div>

Нужна ли она вообще в данном случае?
http://stackoverflow.com/questions/1...el-and-ng-bind

Shitbox2 03.08.2013 23:41

Это выхолощенный пример. Предыдущий был ближе к реальности. Директива отвечает за показ и управление списком элементов (слайдшоу) через jQuery-плагин. Один из элементов должен быть активным. Список элементов берется из ng-model, но если активный элемент меняется, то модель должна обновляться. Стандартная директива option обновляет же модель.

Shitbox2 04.08.2013 19:08

Пример на фазы жизненного цикла http://plnkr.co/edit/cMH4WIezzw6SNyuLYzrm?p=preview


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