【问题标题】:Angular one request for three parts on the pageAngular 1 请求页面上的三个部分
【发布时间】:2015-11-27 02:55:03
【问题描述】:

我有导航栏、主页内容和页脚。在所有这些中,我需要显示相同的数据,但它们位于不同的控制器中。 我尝试在运行阶段执行一个请求并将数据插入服务并共享此数据。但问题是由于承诺模式而导致的延迟。 我试图避免把它放在 rootScope 中。 有人有更好的主意吗?

运行阶段的示例:

    PostsService.getPosts().then(function(data) {
      PostsService.posts = res.data;
    }

the controllers:

//home
    $stateProvider
      .state('home', {
         url: "/",
         controller:HomeController,
         templateUrl: "views/home/index.html"
    });

// nav controller

    $scope.posts= PostsService.posts;

    console.log(PostsService.posts) // is an empty array

the html:

//home view

//return data

    <div ng-repeat="posts in posts">
      <p>{{post.body}}</p>
    </div>

//nav view is not return data

    <section ng-controller="NavController">
    <div ng-repeat="posts in posts">
      <p>{{post.body}}</p>
    </div>
    </section>

//footer
    <section ng-controller="FooterController">
    <div ng-repeat="posts in posts">
      <p>{{post.body}}</p>
    </div>
    </section>

plunker: http://plnkr.co/edit/CmpkURaG3ynIBVxwSpAM?p=preview

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    如果您使用ui-router,您可以将加载逻辑放入状态的resolve(而不是通用的run 函数)以等待状态解析,直到加载完成。然后你可以将解析的本地服务注入到状态的控制器中(你甚至可以在子状态中这样做)。

    $stateProvider.state('home', {
        // ...
        resolve: {
            posts: ['PostsService', function (PostsService) {
                return PostsService.getPosts();
            }]
        },
        controller: ['$scope', 'posts', function ($scope, posts) {
            $scope.posts = posts;
        }]
    });
    

    See documentation.

    【讨论】:

    • 我喜欢这种方法,但我会说避免使用 rootScope。如果 PostService 可以在本地缓存帖子以避免进一步的请求,那么每个控制器都可以根据需要访问 PostService 以获取帖子。
    • 你是对的,在这里使用$rootScope 很讨厌。这只是说明这一点的最短方式。我会改进答案。
    【解决方案2】:

    终于调试了你的 plunker,问题似乎出在对象引用上。

    你正在使用

    UsersService.users = data.res
    

    所以用户在通话前和通话后的参考发生了变化。 在获取数据之前加载 MainCtrl(使用控制台语句确认加载顺序) 之后正在加载 NavCtrl。

    因此 MainCtrl 仍然绑定到旧的用户对象引用,即 [] 并且即使在获取数据后仍继续绑定到该对象,因为此方法创建一个新的用户对象而不是更新旧的对象。

    一个简单的解决方案是保持引用相同,例如:

    app.run(function($http, usersService) {
    
      $http.get('http://jsonplaceholder.typicode.com/users').then(function(res) {
    
        usersService.users.length = 0 ;// empties the user object
        //copy the array
        Array.prototype.push.apply(usersService.users, res.data);
      });
    });
    

    【讨论】:

    • 但是为什么会这样,服务是单例的,引用不应该是一样的?
    • 服务是单例的。但是里面的用户对象不是一个常数,所以它的引用可以变化。初始化数据的时候,给它分配一个空数组,也就是内存位置1。而当你取数据,拿到json的时候,这个数据是不同的内存位置。
    【解决方案3】:

    您能否详细说明“由于承诺模式而延迟”? 与您使用 Service 或 $rootScope 的方式一样,此代码的工作方式应该没有区别。

    【讨论】:

    • 当我在运行阶段执行此操作时,它会在解决承诺之前加载视图
    • 这将有助于查看您的代码以及您的操作方式。你能把它贴出来或者可能是一个笨蛋吗?
    • 我在问题里写了,这是run阶段的代码,你要我加什么?
    • Angular 的视图加载不会因为使用 promise 而延迟。我假设您已将承诺解决方案放在您的路线上。这就是延迟控制器加载和视图加载的方式,直到您从 API 获取数据。您需要为您的路线放置一个解析块。你做过吗?
    • console.log 记录空数组可能有两个原因 1. 您从服务器返回的数据实际上是空的(可能值得调试它)。 2. 当你到达这个控制台块时,你的承诺还没有解决。对于第二种情况,您可能需要查看 PostServices.posts,然后在其中有数据时使用它(直到您仅在视图中使用它)。 Fenex 写的应该行得通。
    【解决方案4】:

    服务是单例的。在模块的所有部分(控制器、工厂等)中,我们的变量ServicePost 指向同一个对象。因此,如果您在“运行”块中更改变量posts,控制器中的值也会发生变化。 为什么不呢?

    JS:

    angular.module('app', ['app.posts-service' /*our service  there*/])
    .run(function(PostsService) {
        PostsService().getPosts().then(function(data) {
            PostsService.posts = res.data;
        })
    })
    .controller('One', function($scope, PostsService) {
        $scope.PostsService = PostService;
    })
    .controller('Two', function($scope, PostsService) {
       $scope.PostsService = PostService;
    });
    

    HTML:

    <div ng:controller="One">
        <ul>
            <my:post ng:repeat="post in PostsService.posts" />
        </ul>
    </div>
    <div ng:controller="Two">
        <ul>
            <my:post ng:repeat="post in PostsService.posts" />
        </ul>
    </div>
    

    【讨论】:

    • 虽然这可能会解决问题,但解释将有助于操作人员和其他用户了解您在那里所做的。
    • 我尝试你的回答并更新我的问题,因为它不起作用
    猜你喜欢
    • 2017-02-28
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 2014-02-16
    相关资源
    最近更新 更多