Контрольное значение модели контроллера контроллера из внутренней директивы
Я пытаюсь иметь 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 секунды изнутри контроллера. Что мне не хватает?
Ответы
Ответ 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