从内部指令监视控制器模型值

Dus*_*tin 22 angularjs angularjs-directive

我试图$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);
            });
        }
    } 
});
Run Code Online (Sandbox Code Playgroud)

因此,$ watch函数没有捕获从控制器内部2秒后完成的模型更改.我错过了什么?

Jon*_*wny 48

$watch接受要在范围内观看的属性的"名称",您要求它观察该值.改变它观看attrs.ngModel哪个返回"bar",现在你正在观看scope.bar.您可以scope[attrs.ngModel]像使用或使用相同的方式获得值,就像再说scope["bar"]一遍,是相同的scope.bar.

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

澄清user271996的注释:scope.$eval是因为您可以将对象表示法传递给ng-model属性.即ng-model="someObj.someProperty"哪些scope["someObj.someProperty"]无效,因为无效.scope.$eval用于将该字符串计算为实际对象,以便scope["someObj.someProperty"]变为scope.someObj.someProperty.

  • 我想只要你在答案的某处包含一个代码示例,SO就会允许小提琴链接. (3认同)
  • 好的,除了应该有console.log("更改为"+范围.$ eval(attrs.ngModel)); (2认同)

wli*_*gke 9

想添加:在1.2.x中,具有独立范围,以上不会起作用.http://jsfiddle.net/TfTr5/23/

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

scope.$watch(
    function(){return controller.$viewValue},
    function(newVal, oldVal){
        //code
    }
)
Run Code Online (Sandbox Code Playgroud)

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

如果有人有其他选择,我很乐意欢迎它!

  • 如果范围是孤立的,那么您无法在父范围内观察事物.这就像hacky一样,但我想更清楚一点:http://jsfiddle.net/TfTr5/25/基本上只是在父范围内进行观察.如果您需要ngModel,并且您的范围是隔离的,那么它应该是安全的.`link:function(scope,element,attrs,controller){scope.$ parent.$ watch(attrs.ngModel,function(){console.log("Changed to"+ scope.$ parent [attrs.ngModel]); }); 但是一般来说我不会孤立需要观察$ parent范围的东西. (3认同)
  • 我完全同意你Johnathan.您的解决方案也有效,但如果我错了,请更正我,$ viewValue不一定与模型值相同吗?请参阅此处:http://jsfiddle.net/TfTr5/27/我相信如果您使用的是angular的表单验证,除非$ viewValue传递验证器,否则它不会更新ngModel.顺便说一句,这是另一个观看ngModel的解决方案 - 但不是$ viewValue - 这是一个更清洁的http://jsfiddle.net/TfTr5/26 (2认同)