Подтвердить что ты не робот

Контрольное значение модели контроллера контроллера из внутренней директивы

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

скрипт: http://jsfiddle.net/dkrotts/TfTr5/5/

function foo($scope, $timeout) {
    $scope.bar = "Lorem ipsum";

    $timeout(function() {
        $scope.bar = "Dolor sit amet";
    }, 2000);
}

myApp.directive('myDirective', function() {
    return {
        restrict: 'A',
        require: '?ngModel',
        link: function (scope, element, attrs, controller) {
            scope.$watch(controller.$viewValue, function() {
                console.log("Changed to " + controller.$viewValue);
            });
        }
    } 
});

Как есть, функция $watch не захватывает изменение модели, сделанное через 2 секунды изнутри контроллера. Что мне не хватает?

4b9b3361

Ответ 1

$watch принимает "имя" свойства для просмотра в области, вы просите его посмотреть значение. Измените его, чтобы посмотреть attrs.ngModel, который возвращает "bar", теперь вы смотрите scope.bar. Вы можете получить значение так же, как и вы, или использовать scope[attrs.ngModel], который похож на выражение scope["bar"], которое снова совпадает с scope.bar.

scope.$watch(attrs.ngModel, function(newValue) {
    console.log("Changed to " + newValue);
});

Чтобы прояснить комментарий пользователя271996: используется scope.$eval, потому что вы можете передать объектную нотацию в атрибут ng-model. т.е. ng-model="someObj.someProperty", который не будет работать, поскольку scope["someObj.someProperty"] недействителен. scope.$eval используется для оценки этой строки в фактическом объекте, так что scope["someObj.someProperty"] становится scope.someObj.someProperty.

Ответ 2

Требуется добавить: в 1.2.x, с изолированной областью, вышеупомянутая не работает. http://jsfiddle.net/TfTr5/23/

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

scope.$watch(
    function(){return controller.$viewValue},
    function(newVal, oldVal){
        //code
    }
)

Рабочая скрипка: http://jsfiddle.net/TfTr5/24/

Если у кого есть альтернатива, я бы с радостью поприветствовал его!

Ответ 3

Если вы хотите связать значение внутри изолированной области видимости, есть два способа сделать это. Первый способ, которым вы можете воспользоваться, даже у вас нет изолированной области. Вот как это сделать:

1) используйте $attrs.any_attribute и привяжите его (установите в часах)

2) используйте 2 способа привязки ('=') и установите его в listener

если вы хотите больше с примерами, вот отличная статья

http://www.w3docs.com/snippets/angularjs/bind-variable-inside-angularjs-directive-isolated-scope.html

Ответ 4

Если вы хотите debounce для значения модели, стоит упомянуть настройку debounce в ng-model-option:

<input type="text" ng-model-options="{ debounce: 1000 }" ng-model="search"/>

Например: эти часы запускают 1000 мс после изменения и reset при новых изменениях.

scope.$watch(attrs.ngModel, function(newValue) { });

https://docs.angularjs.org/api/ng/directive/ngModelOptions