$scope.$watch 在指令中调用服务后不更新

$scope.$watch doesn't update after service call in directive

我有一个加载图像数据模板的指令。

问题是在调用检索 img 信息的服务后,它没有更新图像日期。

这是我的代码:

控制器方法:

$scope.watchImage = function(file_id){
        FileService.getFile(file_id)
        .then(
            function(data){
                if(data.file){
                    $scope.img = data.file; 
                    console.log('Service called');
                }
            }
        );
    }

指令:

app.directive('imageDetails', function() {
    return {
        scope: {
            img: '='
        },
        restrict: 'E',
        link: function($scope, element, attrs){
            $scope.$watch(function() { 
                return $scope.img; 
            }, function() { 
                console.log($scope.img); 
            });
        },
        template: 'IMG: {img}'
    };
});

HTML:

<div class="ui container">
        <h2 class="ui dividing header">Images</h2>
    </div>

    <div ng-view></div>

    <image-details img="img"></image-details>
</div>

日志结果:

undefined
Service called

知道如何解决吗?

谢谢!

您在模板和 link 函数中有一些错误。

var app = angular.module('myApp', []);
app.controller('mainCtrl', function ($scope) {
  $scope.img = {id: 1, title: "avatar.jpeg", slug: "avatar.jpeg", filesize: 24875, created_at: "2016-03-10 11:44:59"};
               
    })

app.directive('imageDetails', function() {
    return {
        scope: {
            img: '='
        },
        restrict: 'E',
        link: function(scope, element, attrs){
            scope.$evalAsync(function() {
           return scope.img; 
       });

        },
        template: 'IMG: {{img}}'
    };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="mainCtrl">


    <image-details img="img"></image-details>
</div>
  

我认为你的指令应该是:

app.directive('imageDetails', function() {
return {
    scope: {
        img: '='
    },
    restrict: 'E',
    link: function(scope, element, attrs){
        scope.$watch('img',function(image) { 
            return image; 
        }, function() { 
            console.log(image); 
        });
    },
    template: 'IMG: {img}'
};
});

首先使用控制器代替 link 函数,因为您不需要它。 Link 函数在 angular 1.5 中被弃用,用于像这样的简单组件。

然后,要使用 $watch,您需要指定要监视的变量,并且只有在它发生变化时才执行的操作。

$watch('varToWatch', function(newValue) {...});

也就是说,如果您使用控制器而不是 link 函数,您可能还会使用 "Controller as" 语法。使用时需要指定要监视的变量的"view name"。例如:

app.directive('imageDetails', function() {
return {
    scope: {
        img: '='
    },
    restrict: 'E',
    controllerAs: '$ctrl',
    controller: function($scope){
        $scope.$watch('$ctrl.img', function(newVal) { 
            console.log(newVal);
            // if you want you can assign new value to your variable
            // $scope.img = newVal;
        });
    },
    template: 'IMG: {img}'
};

});

试试这个,然后告诉我它是否适合你 ;)

这是范围在模块外受到影响的明显案例。对于这些情况,生命周期不会像您期望的那样对范围进行摘要。

当你想通知你的应用你的指令范围已经改变时,你必须手动 $digest 或 $apply

首先感谢大家的回复。他们都帮助我解决了问题。

最后这是我的工作代码。

指令:

app.directive('imageDetails', function() {
    return {
        scope: {
            img: '='
        },
        restrict: 'E',
        template: 'IMG: {{img}}'
    };
});

然后我将指令添加到我的模板中(我在 ngview 之外添加它)。