22

我正在尝试$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 秒后完成的模型更改。我错过了什么?

4

4 回答 4

48

$watch接受要在范围内观察的属性的“名称”,您要求它观察值。将其更改为 watchattrs.ngModel返回“bar”,现在您正在观看scope.bar。您可以以与以前相同的方式获得价值,也可以使用scope[attrs.ngModel]which 就像再说scope["bar"]一遍一样,与scope.bar.

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

澄清 user271996 的评论:scope.$eval使用是因为您可以将对象表示法传递给ng-model属性。即ng-model="someObj.someProperty"因为scope["someObj.someProperty"]无效而不起作用。scope.$eval用于将该字符串评估为实际对象,从而scope["someObj.someProperty"]变为scope.someObj.someProperty.

于 2013-01-28T17:57:23.520 回答
9

想要补充:在 1.2.x 中,在隔离范围内,上述方法不起作用。http://jsfiddle.net/TfTr5/23/

我想出的一个解决方法是使用 $watch 也接受一个函数的事实,因此您可以使用它访问您的控制器。

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

工作小提琴:http: //jsfiddle.net/TfTr5/24/

如果有人有替代品,我很乐意欢迎!

于 2013-12-06T19:33:18.543 回答
1

如果你想在独立作用域内绑定一个值,有两种方法可以做到。第一种方法即使你没有独立作用域也可以使用。方法如下:

1)使用$attrs.any_attribute并绑定它(在手表中设置)

2)使用2路绑定('=')方法并将其设置为监听器

如果您想要更多示例,这里是一篇很棒的文章

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

于 2015-07-22T16:11:11.670 回答
-1

如果你想对模型值进行去抖动,值得一提的是ng-model-option中的去抖动设置:

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

例如:此表在更改后 1000 毫秒触发并在新更改时重置。

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

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

于 2015-06-13T20:16:01.010 回答