AngularJS - 如何使用服务更新视图中的数据?

时间:2015-06-30 03:57:05

标签: angularjs

我将解释到目前为止我所拥有的一切。我有两个controllers,它们都使用我创建的movieService来获取电影列表。控制器是这样的:

app.controller('MovieCtrl', ['$scope', 'movieService', function($scope, movieService) {

  $scope.movieService = movieService;

}]);

app.controller('NavCtrl', ['$scope', 'movieService', function($scope, movieService) {

  $scope.movieService = movieService;

}]);

我的服务如下:

app.service('movieService', ['$http', function($http) {
        var movie = undefined;
        var relatedMovies = undefined;
        var searchTerm = undefined;

        this.update = function(search) {
            searchTerm = search;
            fetch();
        };

        function fetch() {
            $http.get(/* some http call that puts data into movie */);

            $http.get(/* some http call that puts data into relatedMovies */);
        };

}]);

我的相关观看代码:

<input type="text" ng-model="searchTerm" ng-model-options="{debounce: 1500}" ng-change="movieService.update(searchTerm)">

<h1>{{ movieService.movie.Title }}</h1>

所以在我看来,我有一个搜索栏,提交搜索词时会使用movieService.update(searchTerm),这样可以正常工作,因为我可以将fetch()的输出记录到控制台,它会告诉我电影资料。

movie变量中有一个Title变量,所以现在我正在使用{{ movieService.movie.Title }}尝试在视图中显示电影的标题。问题是$scope.movieService数据没有实时更新,因此如果我在service内运行新搜索,除非我手动执行,否则视图中的数据不会更新。当movieService中的数据更新时,视图也应该是。

我的问题就是这样,我如何确保$scope.movieService中的这些controllers变量始终与service保持同步?我应该使用$watch或类似的东西吗?实现这一目标的最佳方法是什么?

更新:添加了CodePen http://codepen.io/anon/pen/JdMxaZ

2 个答案:

答案 0 :(得分:2)

问题是您的movie变量只是服务中的变量。作为服务中的变量,没有任何内容可以赋予变量特殊权力。要在控制器中查看该变量,您需要将其作为服务本身的一部分。该服务只是一个对象,而且是您添加update功能的对象。您需要将movierelatedMovies变量作为服务对象的一部分。

这是解决此问题的一种方法。 movieData对象只是解决此问题的一种方法。无论哪种方式,您都需要更改对象字段的值,而不是本地变量的值。

app.service('movieService', function($http) {
    var movieData = {
        movie: undefined,
        relatedMovies: undefined
    };

    var searchTerm = undefined;

    movieData.update = function(search) {
        // searchTerm is fine because you're not trying to access it from the
        // controller
        searchTerm = search;
        fetch();
    };

    this.movieData = movieData;

    function fetch() {
        $http.get(/* movieData.movie = http data */);
        $http.get(/* movieData.relatedMovies = http data */);
    };
});


app.controller('MovieCtrl', [function($scope, movieService) {
  $scope.movieService = movieService.movieData;
});

app.controller('NavCtrl', function($scope, movieService) {
  $scope.movieService = movieService.movieData;
});

您还可以在服务函数中将变量设置为this的值,并在该变量上更改movierelatedMovies的值。

app.service('movieService', function($http) {
    var movieService = this;
    // modifying this modifies movieService and vice-versa
    this.movie = undefined;
    this.relatedMovies = undefined;

    var searchTerm = undefined;

    this.update = function(search) {
        // searchTerm is fine because you're not trying to access it from the
        // controller
        searchTerm = search;
        fetch();
    };

    function fetch() {
        $http.get(/* movieService.movie = http data */);
        $http.get(/* movieService.relatedMovies = http data */);
    };
});


app.controller('MovieCtrl', [function($scope, movieService) {
  $scope.movieService = movieService;
});

app.controller('NavCtrl', function($scope, movieService) {
  $scope.movieService = movieService;
});

答案 1 :(得分:-1)

我通常将数据存储在$ rootScope中,因此如果您将搜索结果放在$ rootScope中,它将实时刷新。

另一种方法是调用广播$ rootScope。$ broadcast(name,args) 这不太实际